Skip to content

fix(wfctl plugin install): preserve cliCommands + buildHooks in installed plugin.json#612

Merged
intel352 merged 2 commits into
mainfrom
fix/installed-manifest-preserve-clicommands
May 10, 2026
Merged

fix(wfctl plugin install): preserve cliCommands + buildHooks in installed plugin.json#612
intel352 merged 2 commits into
mainfrom
fix/installed-manifest-preserve-clicommands

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

`writeInstalledManifest` constructed `installedPluginCapabilities` from the registry manifest by hand-copying ModuleTypes / StepTypes / TriggerTypes / IaCProvider — but silently dropped `CLICommands` and `BuildHooks`. Result: plugin.json on disk after install had no cliCommands, so `BuildCLIRegistry` could not discover plugin-provided wfctl subcommands.

Reproduction

workflow-registry#28 added `cliCommands: [{name: payments, …}]` to the `workflow-plugin-payments` manifest. Every BMW `provision-stripe-issuing-webhook` retrigger still reported:

```
unknown command: payments
```

Diagnostic on the runner (buymywishlist#260 debug branch run) showed:

```
$ ls -la $WFCTL_PLUGIN_DIR/payments
-rw------- 1 runner runner 1091 plugin.json ← 1KB stub from writeInstalledManifest
-rwxr-xr-x 1 runner runner 73M workflow-plugin-payments

$ jq .capabilities.cliCommands $WFCTL_PLUGIN_DIR/payments/plugin.json
"<>"
```

The 27KB plugin.json the v0.3.1 release tarball shipped with cliCommands was overwritten by writeInstalledManifest's stripped version.

Fix

Extend `installedPluginCapabilities` with `CLICommands` + `BuildHooks` fields and propagate them in `writeInstalledManifest`. The registry-side struct already carries both fields; this just plumbs them through.

Tests

`TestInstalledManifestPreservesCLICommands` — regression guard: read-back of writeInstalledManifest's output must contain CLICommands + BuildHooks the registry manifest declared.

Verification

  • `GOWORK=off go build ./...` clean
  • `GOWORK=off go vet ./...` clean
  • `GOWORK=off go test ./cmd/wfctl/ -count=1 -run "TestInstalledManifest"` green

🤖 Generated with Claude Code

…n.json

`writeInstalledManifest` constructed `installedPluginCapabilities` from
the registry manifest by hand-copying ModuleTypes / StepTypes /
TriggerTypes / IaCProvider — but silently dropped CLICommands and
BuildHooks. Result: plugin.json on disk after install had no
cliCommands, so BuildCLIRegistry could not discover plugin-provided
wfctl subcommands.

Workflow-registry's payments manifest had been updated to declare
`cliCommands: [{name: payments, …}]`, but every BMW
`provision-stripe-issuing-webhook` retrigger still reported
`unknown command: payments` because the field never made it from the
registry manifest to the on-disk plugin.json.

Fix: extend `installedPluginCapabilities` with `CLICommands` +
`BuildHooks` fields and propagate them in writeInstalledManifest.
The registry-side struct already carries both fields; this just
plumbs them through.

Tests: TestInstalledManifestPreservesCLICommands as a regression
guard — read-back of writeInstalledManifest's output must contain the
CLICommands and BuildHooks the registry manifest declared.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 10, 2026 07:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes wfctl plugin install writing an incomplete installed plugin.json by ensuring registry-declared capabilities.cliCommands and capabilities.buildHooks are preserved on disk, enabling plugin-provided wfctl subcommands (and build-hook dispatch) to work post-install.

Changes:

  • Extend installedPluginCapabilities to include CLICommands and BuildHooks.
  • Plumb those fields through writeInstalledManifest so installed plugin.json retains them.
  • Add a regression test ensuring writeInstalledManifest output preserves both cliCommands and buildHooks.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
cmd/wfctl/plugin_install.go Adds CLICommands/BuildHooks to the installed manifest capabilities and writes them out during install.
cmd/wfctl/plugin_install_e2e_test.go Adds a regression test asserting installed plugin.json retains cliCommands + buildHooks.

Comment thread cmd/wfctl/plugin_install_e2e_test.go Outdated
Comment on lines +426 to +431
// TestInstalledManifestPreservesCLICommands is the regression test for the
// post-install plugin-CLI dispatch bug: writeInstalledManifest used to drop
// capabilities.cliCommands, so even when a registry manifest declared them,
// `wfctl <plugin-cmd>` reported `unknown command` because BuildCLIRegistry
// reads from the on-disk plugin.json (not the registry manifest).
func TestInstalledManifestPreservesCLICommands(t *testing.T) {
Comment on lines +446 to +448
BuildHooks: []RegistryBuildHook{
{Event: "pre-build", Priority: 10},
},
Round 2 of #612 Copilot review:
- Test name now reflects both behaviors (CLICommands + BuildHooks).
- BuildHooks fixture event renamed pre-build → pre_build to match
  interfaces.HookEvent* underscore convention. Hyphen variant was a
  placeholder that could mask validation drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 10, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:262: parsing iteration count: invalid syntax
baseline-bench.txt:307283: parsing iteration count: invalid syntax
baseline-bench.txt:636432: parsing iteration count: invalid syntax
baseline-bench.txt:922555: parsing iteration count: invalid syntax
baseline-bench.txt:1253339: parsing iteration count: invalid syntax
baseline-bench.txt:1566660: parsing iteration count: invalid syntax
benchmark-results.txt:262: parsing iteration count: invalid syntax
benchmark-results.txt:328952: parsing iteration count: invalid syntax
benchmark-results.txt:625314: parsing iteration count: invalid syntax
benchmark-results.txt:932230: parsing iteration count: invalid syntax
benchmark-results.txt:1211873: parsing iteration count: invalid syntax
benchmark-results.txt:1543041: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │       sec/op       │    sec/op      vs base              │
InterpreterCreation-4              3.164m ± 223%   3.080m ± 214%       ~ (p=0.699 n=6)
ComponentLoad-4                    3.562m ±  12%   3.626m ±   9%       ~ (p=0.394 n=6)
ComponentExecute-4                 1.886µ ±   7%   1.856µ ±   2%  -1.59% (p=0.015 n=6)
PoolContention/workers-1-4         1.018µ ±   2%   1.048µ ±   3%  +3.00% (p=0.004 n=6)
PoolContention/workers-2-4         1.022µ ±  17%   1.039µ ±   5%       ~ (p=0.145 n=6)
PoolContention/workers-4-4         1.037µ ±   2%   1.031µ ±   1%       ~ (p=0.420 n=6)
PoolContention/workers-8-4         1.048µ ±   8%   1.036µ ±   2%       ~ (p=0.394 n=6)
PoolContention/workers-16-4        1.032µ ±   2%   1.040µ ±   2%       ~ (p=0.452 n=6)
ComponentLifecycle-4               3.647m ±   7%   3.603m ±   2%       ~ (p=0.394 n=6)
SourceValidation-4                 2.137µ ±   2%   2.099µ ±   1%  -1.75% (p=0.002 n=6)
RegistryConcurrent-4               793.0n ±   8%   755.0n ±   3%       ~ (p=0.093 n=6)
LoaderLoadFromString-4             3.714m ±   8%   3.612m ±   1%       ~ (p=0.310 n=6)
geomean                            16.97µ          16.83µ         -0.80%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.608 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.974 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%       ~ (p=0.264 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%  -0.00% (p=0.039 n=6)
geomean                             15.25Ki        15.25Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  301.0n ± 2%   298.0n ± 3%       ~ (p=0.589 n=6)
CircuitBreakerExecution_Success-4          22.67n ± 0%   22.66n ± 0%       ~ (p=0.933 n=6)
CircuitBreakerExecution_Failure-4          70.92n ± 0%   70.97n ± 0%  +0.06% (p=0.030 n=6)
geomean                                    78.51n        78.25n       -0.33%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base              │
JQTransform_Simple-4                     820.0n ± 31%   840.0n ± 30%       ~ (p=0.240 n=6)
JQTransform_ObjectConstruction-4         1.390µ ±  0%   1.415µ ±  1%  +1.76% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.402µ ±  0%   3.533µ ±  1%  +3.85% (p=0.002 n=6)
JQTransform_Complex-4                    41.36µ ±  0%   42.54µ ±  1%  +2.87% (p=0.002 n=6)
JQTransform_Throughput-4                 1.705µ ±  1%   1.761µ ±  2%  +3.31% (p=0.002 n=6)
SSEPublishDelivery-4                     64.26n ±  0%   64.55n ±  0%  +0.46% (p=0.002 n=6)
geomean                                  1.612µ         1.652µ        +2.44%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │     allocs/op      │ allocs/op   vs base                │
JQTransform_Simple-4                     10.00 ± 0%     10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%     15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%     30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%     324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%     17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                   1.084µ ±  2%   1.084µ ±  5%       ~ (p=0.965 n=6)
SchemaValidation_AllFields-4                1.631µ ± 15%   1.639µ ±  6%       ~ (p=0.699 n=6)
SchemaValidation_FormatValidation-4         1.574µ ±  2%   1.631µ ± 15%  +3.65% (p=0.026 n=6)
SchemaValidation_ManySchemas-4              1.627µ ±  3%   1.769µ ±  9%  +8.73% (p=0.006 n=6)
geomean                                     1.459µ         1.505µ        +3.15%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.093µ ± 10%   1.136µ ± 13%        ~ (p=0.699 n=6)
EventStoreAppend_SQLite-4                  1.094m ±  7%   1.040m ±  2%        ~ (p=0.132 n=6)
GetTimeline_InMemory/events-10-4           12.97µ ±  9%   13.72µ ±  2%        ~ (p=0.065 n=6)
GetTimeline_InMemory/events-50-4           57.50µ ± 26%   75.50µ ±  5%  +31.31% (p=0.002 n=6)
GetTimeline_InMemory/events-100-4          114.6µ ±  1%   119.3µ ± 30%   +4.09% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          582.3µ ±  0%   606.6µ ±  2%   +4.18% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.199m ±  3%   1.220m ±  1%        ~ (p=0.132 n=6)
GetTimeline_SQLite/events-10-4             85.18µ ±  4%   87.90µ ±  1%        ~ (p=0.065 n=6)
GetTimeline_SQLite/events-50-4             222.1µ ±  0%   232.0µ ±  1%   +4.46% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            392.9µ ±  0%   414.4µ ±  2%   +5.47% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.707m ±  2%   1.772m ±  1%   +3.83% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.352m ±  3%   3.489m ±  2%   +4.07% (p=0.002 n=6)
geomean                                    195.1µ         205.4µ         +5.30%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  765.0 ± 7%     795.5 ± 6%       ~ (p=0.255 n=6)
EventStoreAppend_SQLite-4                  1.982Ki ± 2%   1.984Ki ± 2%       ~ (p=0.201 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%       ~ (p=0.688 n=6)
geomean                                    67.16Ki        67.38Ki       +0.33%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 merged commit 387438e into main May 10, 2026
18 checks passed
@intel352 intel352 deleted the fix/installed-manifest-preserve-clicommands branch May 10, 2026 08:04
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

Successfully merging this pull request may close these issues.

2 participants