diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Microsoft.CmdPal.Ext.Actions.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Microsoft.CmdPal.Ext.Actions.csproj
index 9af3c03032..a229fa4537 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Microsoft.CmdPal.Ext.Actions.csproj
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Microsoft.CmdPal.Ext.Actions.csproj
@@ -25,13 +25,13 @@
+
+
+
PreserveNewest
-
-
-
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Parameters.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Parameters.cs
deleted file mode 100644
index 65951c13d5..0000000000
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Actions/Parameters.cs
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using Windows.Foundation;
-using Windows.Storage;
-using Windows.Storage.Pickers;
-
-namespace Microsoft.CommandPalette.Extensions.Toolkit;
-
-#pragma warning disable SA1402 // File may only contain a single type
-#pragma warning disable SA1649 // File name should match first type name
-#nullable enable
-public interface IRequiresHostHwnd
-{
- void SetHostHwnd(nint hostHwnd);
-}
-
-public partial class LabelRun : BaseObservable, ILabelRun
-{
- private string? _text = string.Empty;
-
- public virtual string? Text
- {
- get => _text;
- set
- {
- _text = value;
- OnPropertyChanged(nameof(Text));
- }
- }
-
- public LabelRun(string text)
- {
- _text = text;
- }
-
- public LabelRun()
- {
- }
-}
-
-public abstract partial class ParameterValueRun : BaseObservable, IParameterValueRun
-{
- private string _placeholderText = string.Empty;
-
- public virtual string PlaceholderText
- {
- get => _placeholderText;
- set
- {
- _placeholderText = value;
- OnPropertyChanged(nameof(PlaceholderText));
- }
- }
-
- private bool _needsValue = true;
-
- // _required | _needsValue | out
- // F | F | T
- // F | T | T
- // T | F | F
- // T | T | T
- public virtual bool NeedsValue
- {
- get => !_required || _needsValue;
- set
- {
- _needsValue = value;
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- // Toolkit helper
- private bool _required = true;
-
- public virtual bool Required
- {
- get => _required;
- set
- {
- _required = value;
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public abstract void ClearValue();
-
- public abstract object? Value { get; set; }
-}
-
-public partial class StringParameterRun : ParameterValueRun, IStringParameterRun
-{
- private string _text = string.Empty;
-
- public virtual string Text
- {
- get => _text;
- set
- {
- _text = value;
- OnPropertyChanged(nameof(Text));
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public override bool NeedsValue => string.IsNullOrEmpty(Text);
-
- public StringParameterRun()
- {
- }
-
- public StringParameterRun(string placeholderText)
- {
- PlaceholderText = placeholderText;
- }
-
- public override void ClearValue()
- {
- Text = string.Empty;
- }
-
- public override object? Value { get => Text; set => Text = (value is string s) ? s : string.Empty; }
-}
-
-public partial class CommandParameterRun : ParameterValueRun, ICommandParameterRun
-{
- private string? _displayText;
-
- public virtual string? DisplayText
- {
- get => _displayText;
- set
- {
- _displayText = value;
- OnPropertyChanged(nameof(DisplayText));
- }
- }
-
- private ICommand? _command;
-
- public virtual ICommand? Command
- {
- get => _command;
- set
- {
- _command = value;
- OnPropertyChanged(nameof(Command));
- }
- }
-
- private IIconInfo? _icon;
-
- public virtual IIconInfo? Icon
- {
- get => _icon;
- set
- {
- _icon = value;
- OnPropertyChanged(nameof(Icon));
- }
- }
-
- public override bool NeedsValue => Value == null;
-
- public virtual ICommand? GetSelectValueCommand(ulong hostHwnd)
- {
- if (Command is IRequiresHostHwnd requiresHwnd)
- {
- requiresHwnd.SetHostHwnd((nint)hostHwnd);
- }
-
- return Command;
- }
-
- // Toolkit helper: a value for the parameter
- private object? _value;
-
- public override object? Value
- {
- get => _value;
- set
- {
- _value = value;
- OnPropertyChanged(nameof(Value));
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public override void ClearValue()
- {
- Value = null;
- }
-}
-
-public partial class FilePickerParameterRun : CommandParameterRun
-{
- public StorageFile? File { get; private set; }
-
- public override object? Value => File;
-
- public override string? DisplayText { get => File != null ? File.DisplayName : "Select a file"; }
-
- public Action? SetupFilePicker { get; set; }
-
- public FilePickerParameterRun()
- {
- var command = new FilePickerCommand();
- command.FileSelected += (s, file) =>
- {
- File = file;
-
- // Value = file != null ? file : (object?)null;
- // OnPropertyChanged(nameof(Value));
- OnPropertyChanged(nameof(NeedsValue));
- OnPropertyChanged(nameof(DisplayText));
- };
- command.RequestCustomizePicker += ConfigureFilePicker;
- PlaceholderText = "Select a file";
- Icon = new IconInfo("\uE710"); // Add
- Command = command;
- }
-
- public override void ClearValue()
- {
- File = null;
- }
-
- private sealed partial class FilePickerCommand : InvokableCommand, IRequiresHostHwnd
- {
- public override IconInfo Icon => new("\uE710"); // Add
-
- public override string Name => "Pick a file";
-
- public event EventHandler? FileSelected;
-
- public event EventHandler? RequestCustomizePicker;
-
- private nint _hostHwnd;
-
- public void SetHostHwnd(nint hostHwnd)
- {
- _hostHwnd = hostHwnd;
- }
-
- public override ICommandResult Invoke()
- {
- PickFileAsync();
- return CommandResult.KeepOpen();
- }
-
- private async void PickFileAsync()
- {
- var picker = new FileOpenPicker() { };
-
- RequestCustomizePicker?.Invoke(this, picker);
-
- // You need to initialize the picker with a window handle in WinUI 3 desktop apps
- // See https://learn.microsoft.com/en-us/windows/apps/design/controls/file-open-picker
- WinRT.Interop.InitializeWithWindow.Initialize(picker, (nint)_hostHwnd);
-
- var file = await picker.PickSingleFileAsync();
- FileSelected?.Invoke(this, file);
- }
- }
-
- protected virtual void ConfigureFilePicker(object? sender, FileOpenPicker picker)
- {
- picker.FileTypeFilter.Add("*");
- }
-}
-
-public partial class SelectParameterCommand : InvokableCommand
-{
- public event TypedEventHandler
diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/Parameters.cs b/src/modules/cmdpal/ext/SamplePagesExtension/Parameters.cs
deleted file mode 100644
index 65951c13d5..0000000000
--- a/src/modules/cmdpal/ext/SamplePagesExtension/Parameters.cs
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (c) Microsoft Corporation
-// The Microsoft Corporation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using Windows.Foundation;
-using Windows.Storage;
-using Windows.Storage.Pickers;
-
-namespace Microsoft.CommandPalette.Extensions.Toolkit;
-
-#pragma warning disable SA1402 // File may only contain a single type
-#pragma warning disable SA1649 // File name should match first type name
-#nullable enable
-public interface IRequiresHostHwnd
-{
- void SetHostHwnd(nint hostHwnd);
-}
-
-public partial class LabelRun : BaseObservable, ILabelRun
-{
- private string? _text = string.Empty;
-
- public virtual string? Text
- {
- get => _text;
- set
- {
- _text = value;
- OnPropertyChanged(nameof(Text));
- }
- }
-
- public LabelRun(string text)
- {
- _text = text;
- }
-
- public LabelRun()
- {
- }
-}
-
-public abstract partial class ParameterValueRun : BaseObservable, IParameterValueRun
-{
- private string _placeholderText = string.Empty;
-
- public virtual string PlaceholderText
- {
- get => _placeholderText;
- set
- {
- _placeholderText = value;
- OnPropertyChanged(nameof(PlaceholderText));
- }
- }
-
- private bool _needsValue = true;
-
- // _required | _needsValue | out
- // F | F | T
- // F | T | T
- // T | F | F
- // T | T | T
- public virtual bool NeedsValue
- {
- get => !_required || _needsValue;
- set
- {
- _needsValue = value;
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- // Toolkit helper
- private bool _required = true;
-
- public virtual bool Required
- {
- get => _required;
- set
- {
- _required = value;
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public abstract void ClearValue();
-
- public abstract object? Value { get; set; }
-}
-
-public partial class StringParameterRun : ParameterValueRun, IStringParameterRun
-{
- private string _text = string.Empty;
-
- public virtual string Text
- {
- get => _text;
- set
- {
- _text = value;
- OnPropertyChanged(nameof(Text));
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public override bool NeedsValue => string.IsNullOrEmpty(Text);
-
- public StringParameterRun()
- {
- }
-
- public StringParameterRun(string placeholderText)
- {
- PlaceholderText = placeholderText;
- }
-
- public override void ClearValue()
- {
- Text = string.Empty;
- }
-
- public override object? Value { get => Text; set => Text = (value is string s) ? s : string.Empty; }
-}
-
-public partial class CommandParameterRun : ParameterValueRun, ICommandParameterRun
-{
- private string? _displayText;
-
- public virtual string? DisplayText
- {
- get => _displayText;
- set
- {
- _displayText = value;
- OnPropertyChanged(nameof(DisplayText));
- }
- }
-
- private ICommand? _command;
-
- public virtual ICommand? Command
- {
- get => _command;
- set
- {
- _command = value;
- OnPropertyChanged(nameof(Command));
- }
- }
-
- private IIconInfo? _icon;
-
- public virtual IIconInfo? Icon
- {
- get => _icon;
- set
- {
- _icon = value;
- OnPropertyChanged(nameof(Icon));
- }
- }
-
- public override bool NeedsValue => Value == null;
-
- public virtual ICommand? GetSelectValueCommand(ulong hostHwnd)
- {
- if (Command is IRequiresHostHwnd requiresHwnd)
- {
- requiresHwnd.SetHostHwnd((nint)hostHwnd);
- }
-
- return Command;
- }
-
- // Toolkit helper: a value for the parameter
- private object? _value;
-
- public override object? Value
- {
- get => _value;
- set
- {
- _value = value;
- OnPropertyChanged(nameof(Value));
- OnPropertyChanged(nameof(NeedsValue));
- }
- }
-
- public override void ClearValue()
- {
- Value = null;
- }
-}
-
-public partial class FilePickerParameterRun : CommandParameterRun
-{
- public StorageFile? File { get; private set; }
-
- public override object? Value => File;
-
- public override string? DisplayText { get => File != null ? File.DisplayName : "Select a file"; }
-
- public Action? SetupFilePicker { get; set; }
-
- public FilePickerParameterRun()
- {
- var command = new FilePickerCommand();
- command.FileSelected += (s, file) =>
- {
- File = file;
-
- // Value = file != null ? file : (object?)null;
- // OnPropertyChanged(nameof(Value));
- OnPropertyChanged(nameof(NeedsValue));
- OnPropertyChanged(nameof(DisplayText));
- };
- command.RequestCustomizePicker += ConfigureFilePicker;
- PlaceholderText = "Select a file";
- Icon = new IconInfo("\uE710"); // Add
- Command = command;
- }
-
- public override void ClearValue()
- {
- File = null;
- }
-
- private sealed partial class FilePickerCommand : InvokableCommand, IRequiresHostHwnd
- {
- public override IconInfo Icon => new("\uE710"); // Add
-
- public override string Name => "Pick a file";
-
- public event EventHandler? FileSelected;
-
- public event EventHandler? RequestCustomizePicker;
-
- private nint _hostHwnd;
-
- public void SetHostHwnd(nint hostHwnd)
- {
- _hostHwnd = hostHwnd;
- }
-
- public override ICommandResult Invoke()
- {
- PickFileAsync();
- return CommandResult.KeepOpen();
- }
-
- private async void PickFileAsync()
- {
- var picker = new FileOpenPicker() { };
-
- RequestCustomizePicker?.Invoke(this, picker);
-
- // You need to initialize the picker with a window handle in WinUI 3 desktop apps
- // See https://learn.microsoft.com/en-us/windows/apps/design/controls/file-open-picker
- WinRT.Interop.InitializeWithWindow.Initialize(picker, (nint)_hostHwnd);
-
- var file = await picker.PickSingleFileAsync();
- FileSelected?.Invoke(this, file);
- }
- }
-
- protected virtual void ConfigureFilePicker(object? sender, FileOpenPicker picker)
- {
- picker.FileTypeFilter.Add("*");
- }
-}
-
-public partial class SelectParameterCommand : InvokableCommand
-{
- public event TypedEventHandler? ValueSelected;
-
- private T _value;
-
- public T Value
- {
- get => _value; protected set { _value = value; }
- }
-
- public SelectParameterCommand(T value)
- {
- _value = value;
- }
-
- public override ICommandResult Invoke()
- {
- ValueSelected?.Invoke(this, _value);
- return CommandResult.KeepOpen();
- }
-}
-
-public partial class StaticParameterList : ListPage
-{
- public event TypedEventHandler? ValueSelected;
-
- private readonly IEnumerable _values;
- private readonly List _items = new();
- private bool _isInitialized;
- private Func _customizeListItemsCallback;
-
- // ctor takes an IEnumerable values, and a function to customize the ListItem's depending on the value
- public StaticParameterList(IEnumerable values, Func customizeListItem)
- {
- _values = values;
- _customizeListItemsCallback = (value, listItem) =>
- {
- customizeListItem(value);
- return listItem;
- };
- }
-
- public StaticParameterList(IEnumerable values, Func customizeListItem)
- {
- _values = values;
- _customizeListItemsCallback = customizeListItem;
- }
-
- public override IListItem[] GetItems()
- {
- if (!_isInitialized)
- {
- Initialize(_values, _customizeListItemsCallback);
- _isInitialized = true;
- }
-
- return _items.ToArray();
- }
-
- private void Initialize(IEnumerable values, Func customizeListItem)
- {
- foreach (var value in values)
- {
- var command = new SelectParameterCommand(value);
- command.ValueSelected += (s, v) => ValueSelected?.Invoke(this, v);
- var listItem = new ListItem(command);
- var item = customizeListItem(value, listItem);
- _items.Add(item);
- }
- }
-}
-
-public abstract partial class ParametersPage : Page, IParametersPage
-{
- public abstract IListItem Command { get; }
-
- public abstract IParameterRun[] Parameters { get; }
-}
-
-#pragma warning restore SA1649 // File name should match first type name
-#pragma warning restore SA1402 // File may only contain a single type
-#nullable disable
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/CommandParameterRun.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/CommandParameterRun.cs
new file mode 100644
index 0000000000..850395ad54
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/CommandParameterRun.cs
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class CommandParameterRun : ParameterValueRun, ICommandParameterRun
+{
+ private string? _displayText;
+
+ public virtual string? DisplayText
+ {
+ get => _displayText;
+ set
+ {
+ _displayText = value;
+ OnPropertyChanged(nameof(DisplayText));
+ }
+ }
+
+ private ICommand? _command;
+
+ public virtual ICommand? Command
+ {
+ get => _command;
+ set
+ {
+ _command = value;
+ OnPropertyChanged(nameof(Command));
+ }
+ }
+
+ private IIconInfo? _icon;
+
+ public virtual IIconInfo? Icon
+ {
+ get => _icon;
+ set
+ {
+ _icon = value;
+ OnPropertyChanged(nameof(Icon));
+ }
+ }
+
+ public override bool NeedsValue => Value == null;
+
+ public virtual ICommand? GetSelectValueCommand(ulong hostHwnd)
+ {
+ if (Command is IRequiresHostHwnd requiresHwnd)
+ {
+ requiresHwnd.SetHostHwnd((nint)hostHwnd);
+ }
+
+ return Command;
+ }
+
+ // Toolkit helper: a value for the parameter
+ private object? _value;
+
+ public override object? Value
+ {
+ get => _value;
+ set
+ {
+ _value = value;
+ OnPropertyChanged(nameof(Value));
+ OnPropertyChanged(nameof(NeedsValue));
+ }
+ }
+
+ public override void ClearValue()
+ {
+ Value = null;
+ }
+}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/FilePickerParameterRun.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/FilePickerParameterRun.cs
new file mode 100644
index 0000000000..7580725dde
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/FilePickerParameterRun.cs
@@ -0,0 +1,89 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Windows.Storage;
+using Windows.Storage.Pickers;
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class FilePickerParameterRun : CommandParameterRun
+{
+ public StorageFile? File { get; private set; }
+
+ public override object? Value => File;
+
+ public override string? DisplayText { get => File != null ? File.DisplayName : "Select a file"; }
+
+ public Action? SetupFilePicker { get; set; }
+
+ public FilePickerParameterRun()
+ {
+ var command = new FilePickerCommand();
+ command.FileSelected += (s, file) =>
+ {
+ File = file;
+
+ // Value = file != null ? file : (object?)null;
+ // OnPropertyChanged(nameof(Value));
+ OnPropertyChanged(nameof(NeedsValue));
+ OnPropertyChanged(nameof(DisplayText));
+ };
+ command.RequestCustomizePicker += ConfigureFilePicker;
+ PlaceholderText = "Select a file";
+ Icon = new IconInfo("\uE710"); // Add
+ Command = command;
+ }
+
+ public override void ClearValue()
+ {
+ File = null;
+ }
+
+ private sealed partial class FilePickerCommand : InvokableCommand, IRequiresHostHwnd
+ {
+ public override IconInfo Icon => new("\uE710"); // Add
+
+ public override string Name => "Pick a file";
+
+ public event EventHandler? FileSelected;
+
+ public event EventHandler? RequestCustomizePicker;
+
+ private nint _hostHwnd;
+
+ public void SetHostHwnd(nint hostHwnd)
+ {
+ _hostHwnd = hostHwnd;
+ }
+
+ public override ICommandResult Invoke()
+ {
+ PickFileAsync();
+ return CommandResult.KeepOpen();
+ }
+
+ private async void PickFileAsync()
+ {
+ var picker = new FileOpenPicker() { };
+
+ RequestCustomizePicker?.Invoke(this, picker);
+
+ // You need to initialize the picker with a window handle in WinUI 3 desktop apps
+ // See https://learn.microsoft.com/en-us/windows/apps/design/controls/file-open-picker
+ WinRT.Interop.InitializeWithWindow.Initialize(picker, (nint)_hostHwnd);
+
+ var file = await picker.PickSingleFileAsync();
+ FileSelected?.Invoke(this, file);
+ }
+ }
+
+ protected virtual void ConfigureFilePicker(object? sender, FileOpenPicker picker)
+ {
+ picker.FileTypeFilter.Add("*");
+ }
+}
+
+#pragma warning restore SA1649 // File name should match first type name
+#pragma warning restore SA1402 // File may only contain a single type
+#nullable disable
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/IRequiresHostHwnd.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/IRequiresHostHwnd.cs
new file mode 100644
index 0000000000..f64b30b696
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/IRequiresHostHwnd.cs
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public interface IRequiresHostHwnd
+{
+ void SetHostHwnd(nint hostHwnd);
+}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/LabelRun.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/LabelRun.cs
new file mode 100644
index 0000000000..803e40a1d5
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/LabelRun.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class LabelRun : BaseObservable, ILabelRun
+{
+ private string? _text = string.Empty;
+
+ public virtual string? Text
+ {
+ get => _text;
+ set
+ {
+ _text = value;
+ OnPropertyChanged(nameof(Text));
+ }
+ }
+
+ public LabelRun(string text)
+ {
+ _text = text;
+ }
+
+ public LabelRun()
+ {
+ }
+}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParameterValueRun.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParameterValueRun.cs
new file mode 100644
index 0000000000..bbed54f8b2
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParameterValueRun.cs
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+#nullable enable
+public abstract partial class ParameterValueRun : BaseObservable, IParameterValueRun
+{
+ private string _placeholderText = string.Empty;
+
+ public virtual string PlaceholderText
+ {
+ get => _placeholderText;
+ set
+ {
+ _placeholderText = value;
+ OnPropertyChanged(nameof(PlaceholderText));
+ }
+ }
+
+ private bool _needsValue = true;
+
+ // _required | _needsValue | out
+ // F | F | T
+ // F | T | T
+ // T | F | F
+ // T | T | T
+ public virtual bool NeedsValue
+ {
+ get => !_required || _needsValue;
+ set
+ {
+ _needsValue = value;
+ OnPropertyChanged(nameof(NeedsValue));
+ }
+ }
+
+ // Toolkit helper
+ private bool _required = true;
+
+ public virtual bool Required
+ {
+ get => _required;
+ set
+ {
+ _required = value;
+ OnPropertyChanged(nameof(NeedsValue));
+ }
+ }
+
+ public abstract void ClearValue();
+
+ public abstract object? Value { get; set; }
+}
+#nullable disable
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParametersPage.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParametersPage.cs
new file mode 100644
index 0000000000..09332e79db
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/ParametersPage.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public abstract partial class ParametersPage : Page, IParametersPage
+{
+ public abstract IListItem Command { get; }
+
+ public abstract IParameterRun[] Parameters { get; }
+}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/SelectParameterCommand.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/SelectParameterCommand.cs
new file mode 100644
index 0000000000..9a5ec79830
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/SelectParameterCommand.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Windows.Foundation;
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class SelectParameterCommand : InvokableCommand
+{
+ public event TypedEventHandler? ValueSelected;
+
+ private T _value;
+
+ public T Value
+ {
+ get => _value; protected set { _value = value; }
+ }
+
+ public SelectParameterCommand(T value)
+ {
+ _value = value;
+ }
+
+ public override ICommandResult Invoke()
+ {
+ ValueSelected?.Invoke(this, _value);
+ return CommandResult.KeepOpen();
+ }
+}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StaticParameterList.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StaticParameterList.cs
new file mode 100644
index 0000000000..3206d3d34e
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StaticParameterList.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Windows.Foundation;
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class StaticParameterList : ListPage
+{
+ public event TypedEventHandler? ValueSelected;
+
+ private readonly IEnumerable _values;
+ private readonly List _items = new();
+ private bool _isInitialized;
+ private Func _customizeListItemsCallback;
+
+ // ctor takes an IEnumerable values, and a function to customize the ListItem's depending on the value
+ public StaticParameterList(IEnumerable values, Func customizeListItem)
+ {
+ _values = values;
+ _customizeListItemsCallback = (value, listItem) =>
+ {
+ customizeListItem(value);
+ return listItem;
+ };
+ }
+
+ public StaticParameterList(IEnumerable values, Func customizeListItem)
+ {
+ _values = values;
+ _customizeListItemsCallback = customizeListItem;
+ }
+
+ public override IListItem[] GetItems()
+ {
+ if (!_isInitialized)
+ {
+ Initialize(_values, _customizeListItemsCallback);
+ _isInitialized = true;
+ }
+
+ return _items.ToArray();
+ }
+
+ private void Initialize(IEnumerable values, Func customizeListItem)
+ {
+ foreach (var value in values)
+ {
+ var command = new SelectParameterCommand(value);
+ command.ValueSelected += (s, v) => ValueSelected?.Invoke(this, v);
+ var listItem = new ListItem(command);
+ var item = customizeListItem(value, listItem);
+ _items.Add(item);
+ }
+ }
+}
+
+#pragma warning restore SA1649 // File name should match first type name
+#pragma warning restore SA1402 // File may only contain a single type
+#nullable disable
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StringParameterRun.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StringParameterRun.cs
new file mode 100644
index 0000000000..a1a92ff570
--- /dev/null
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Parameters/StringParameterRun.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
+
+public partial class StringParameterRun : ParameterValueRun, IStringParameterRun
+{
+ private string _text = string.Empty;
+
+ public virtual string Text
+ {
+ get => _text;
+ set
+ {
+ _text = value;
+ OnPropertyChanged(nameof(Text));
+ OnPropertyChanged(nameof(NeedsValue));
+ }
+ }
+
+ public override bool NeedsValue => string.IsNullOrEmpty(Text);
+
+ public StringParameterRun()
+ {
+ }
+
+ public StringParameterRun(string placeholderText)
+ {
+ PlaceholderText = placeholderText;
+ }
+
+ public override void ClearValue()
+ {
+ Text = string.Empty;
+ }
+
+ public override object? Value { get => Text; set => Text = (value is string s) ? s : string.Empty; }
+}