Reimaginate.CLI.Base 1.0.0-rc.88

This is a prerelease version of Reimaginate.CLI.Base.
dotnet add package Reimaginate.CLI.Base --version 1.0.0-rc.88
                    
NuGet\Install-Package Reimaginate.CLI.Base -Version 1.0.0-rc.88
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Reimaginate.CLI.Base" Version="1.0.0-rc.88" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Reimaginate.CLI.Base" Version="1.0.0-rc.88" />
                    
Directory.Packages.props
<PackageReference Include="Reimaginate.CLI.Base" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Reimaginate.CLI.Base --version 1.0.0-rc.88
                    
#r "nuget: Reimaginate.CLI.Base, 1.0.0-rc.88"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Reimaginate.CLI.Base@1.0.0-rc.88
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Reimaginate.CLI.Base&version=1.0.0-rc.88&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Reimaginate.CLI.Base&version=1.0.0-rc.88&prerelease
                    
Install as a Cake Tool

Reimaginate CLI

Reimaginate CLI provides composable .NET command modules for building an internal CLI host. Each package contributes command registrations and command implementations for a specific tool area, so applications can install only the modules they need.

The packages are designed to be consumed by a host application that wires Microsoft.Extensions.Hosting, dependency injection, System.CommandLine, and one or more Reimaginate CLI command modules.

Packages

Package Purpose
Reimaginate.CLI.Base Core command abstractions, shared verbs, stash helpers, token preprocessing, and root command helpers.
Reimaginate.CLI.Microsoft.ACS.Tools Azure Container Apps commands for listing, exporting, copying, deploying, stopping, scaling, and updating apps and jobs.
Reimaginate.CLI.Microsoft.AZCost.Tools Azure cost list and export commands.
Reimaginate.CLI.Microsoft.CRM.Tools Dynamics 365 and Dataverse commands for list, export, CRUD data operations, compare, copy, activate, deactivate, and user role/team operations.
Reimaginate.CLI.Microsoft.ServiceBus.Tools Azure Service Bus commands for listing queues, resubmitting dead-letter messages, and copying namespace or queue topology.

Installation

Install the base package and the command modules your host needs:

dotnet add package Reimaginate.CLI.Base
dotnet add package Reimaginate.CLI.Microsoft.ACS.Tools
dotnet add package Reimaginate.CLI.Microsoft.AZCost.Tools
dotnet add package Reimaginate.CLI.Microsoft.CRM.Tools
dotnet add package Reimaginate.CLI.Microsoft.ServiceBus.Tools

Command modules reference Reimaginate.CLI.Base, so installing a module also brings in the shared CLI foundation.

Quick Start

The host owns application startup and chooses which command modules to expose:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Reimaginate.CLI.Base.Config;
using Reimaginate.CLI.Base.Helpers;
using Reimaginate.CLI.Microsoft.ACS.Tools.Config;
using Reimaginate.CLI.Microsoft.AZCost.Tools.Config;
using Reimaginate.CLI.Microsoft.CRM.Tools.Config;
using Reimaginate.CLI.Microsoft.ServiceBus.Tools.Config;
using Reimaginate.Mediator;
using System.CommandLine;

var builder = Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostingContext, configuration) =>
    {
        configuration.Sources.Clear();
        configuration.AddEnvironmentVariables();
    })
    .ConfigureServices((hostContext, services) =>
    {
        services.AddSingleton<IMediator, AppMediator>();
        AppMediator.RegisterHandlers(services);

        services.AddMicrosoftAcsCliCommands(hostContext.Configuration);
        services.AddMicrosofAzCostCliCommands(hostContext.Configuration);
        services.AddMicrosoftCrmCliCommands(hostContext.Configuration);
        services.AddMicrosoftServiceBusCliCommands(hostContext.Configuration);
    })
    .ConfigureLogging(logging => logging.ClearProviders());

using var app = builder.Build();
await app.StartAsync();

var rootCommand = new RootCommand();
rootCommand.AddBaseCommands(app.Services);
rootCommand.AddMicrosoftAcsTools(app.Services);
rootCommand.AddMicrosoftAzCostTools(app.Services);
rootCommand.AddMicrosoftCrmTools(app.Services);
rootCommand.AddMicrosoftServiceBusTools(app.Services);

var processedArgs = await ArgumentsPreprocessor.ReplaceTokens(args);
var exitCode = await rootCommand.Trim().Parse(processedArgs).InvokeAsync();

await app.StopAsync();
return exitCode;

AppMediator is the application's mediator implementation. The test host in this repository uses the generated mediator pattern from Reimaginate Mediator; applications can use the same approach or provide another IMediator implementation that can dispatch the registered CLI requests.

Dynamic Tool Packages

Hosts can also load command modules from NuGet at runtime by using the dynamic tool runtime in Reimaginate.CLI.Base. A package can expose an ICliToolModule implementation to register its services and commands, or the runtime can fall back to scanning the package assembly for existing TopLevelCommand, SubCommand<>, and IHandler<TRequest,TResponse> types.

The base package adds these commands:

tools install <package-id> --version <version> --source <source> --yes
tools update <package-id> --version <version> --source <source> --prerelease --yes
tools list
tools remove <package-id> --yes
tools restore

Dynamic installs and updates are explicit trust decisions. tools install and tools update warn that the package will execute local .NET code on future CLI runs, and installs pin the resolved package version in the local manifest under the user's Reimaginate CLI app data folder. Newly installed or updated commands are loaded on the next process run.

Hosts can bundle dynamic tools by shipping .nupkg files in an app-relative bundled-tools directory. Bundled tools are loaded before user-installed tools, are not written to the user manifest, and cannot be removed with tools remove. tools list shows whether each tool came from the application bundle or the user's local tool manifest.

The test host wires the dynamic runtime as a proof host: it loads bundled and installed modules before building dependency injection, uses the reflection-based mediator from Reimaginate.CLI.Base, and adds dynamic root commands after the service provider is built.

See Dynamic and Bundled CLI Tools for host and operator guidance, and Dynamic Tool Package Authoring for package authoring guidance.

Sample Hosts

Reference host projects are available under samples:

Sample Demonstrates
Reimaginate.CLI.Samples.CompiledHost A compiled-in host that directly references first-party tool projects.
Reimaginate.CLI.Samples.DynamicUserToolsHost A base host that supports user-installed dynamic tools without bundled packages.
Reimaginate.CLI.Samples.DynamicBundledToolsHost A dynamic host that loads app-bundled .nupkg tools before user-installed tools.

Command Areas

First-party tools use an Azure CLI-style command surface: <tool> <resource-group> <command>. This release is a hard cutover from the older verb-first shape, so paths such as acs list jobs, d365 export users, and service-bus copy queues are no longer registered.

Area Top-level command Capabilities
Base stash and shared verbs Store reusable values, preprocess command tokens, and provide shared command scaffolding.
Azure Container Apps acs List apps/jobs, export app/job definitions, copy resources with patches, deploy jobs, stop executions, scale apps/jobs, and update apps/jobs.
Azure Cost azcost List and export Azure cost data for a subscription and date range.
Dynamics 365 / Dataverse d365 Manage Dataverse data, metadata, automation assets, security assignments, solutions, and marketing segments.
Azure Service Bus service-bus List queues, resubmit dead-letter messages, copy namespaces, and copy queues between namespaces.

Use the generated command help from your host application for the complete command and option reference. See Azure Container Apps CLI Commands for ACS app scale examples and scale rule file shape.

Dynamics 365 data CRUD

Generic Dataverse data operations are available under d365 data:

d365 data get --url https://org.crm.dynamics.com --entity account --id <guid> --format json
d365 data list --url https://org.crm.dynamics.com --entity account --props name,modifiedon --where "statecode=0" --sort "-modifiedon" --limit 100
d365 data list --url https://org.crm.dynamics.com --entity account --view "Active Accounts" --where "modifiedon>=2026-01-01"
d365 data list --url https://org.crm.dynamics.com --entity account --fetchxml-file .\accounts.fetchxml --limit 100
d365 data export --url https://org.crm.dynamics.com --entity account --props accountid,name --out .\accounts.md
d365 data count --url https://org.crm.dynamics.com --entity account --view "Active Accounts"
d365 data count --url https://org.crm.dynamics.com --entity account --view "Active Accounts" --method paged
d365 data count --url https://org.crm.dynamics.com --entity contact --where "statecode=0,emailaddress1~@example.com"
d365 data duplicates --url https://org.crm.dynamics.com --entity contact --columns emailaddress1
d365 data create --url https://org.crm.dynamics.com --entity account --values '{ "name": "Sample" }' --yes
d365 data update --url https://org.crm.dynamics.com --entity account --id <guid> --set "name=Updated,statuscode:option=1" --yes
d365 data delete --url https://org.crm.dynamics.com --entity account --id <guid> --yes
d365 data delete --url https://org.crm.dynamics.com --entity contact --where "statecode=1" --dry-run --props fullname,emailaddress1
d365 data delete --url https://org.crm.dynamics.com --entity contact --where "statecode=1" --max-records 500

Dynamics 365 commands are grouped by domain:

d365 data get|list|export|create|update|delete|count|duplicates
d365 metadata entities list|export|describe
d365 metadata fields list|export
d365 metadata relationships list|export
d365 metadata forms list|export
d365 metadata views list|export
d365 metadata option-sets list|export
d365 metadata event-handlers list|export
d365 automation workflows list|export|activate|deactivate
d365 automation cloud-flows list|export
d365 automation plugin-assemblies list|export
d365 security users list|export
d365 security roles list|export|assign|copy|compare
d365 security teams list|export|copy|compare
d365 security permissions list|export|compare
d365 solutions list|export
d365 marketing segments list|export

This is a hard cutover from the previous D365 resource layout. Paths such as d365 entities export-data, d365 users copy-roles, and d365 workflows export-all are no longer registered.

d365 data count --where applies server-side FetchXML conditions. Use comma-separated AND conditions with =, !=, >, >=, <, <=, ~, !~, :null, and :not-null; ~ and !~ map to contains-style like and not-like filters.

d365 data count supports --method auto|aggregate|paged. auto is the default: plain entity counts use aggregate counting with paged fallback for Dataverse's 50,000 aggregate limit, while saved-view counts use paged counting by default so the result follows the actual view rows more closely. Use --method aggregate only when you specifically want the faster aggregate rewrite.

d365 data list can use simple command-line query options, a saved view, or explicit FetchXML. In simple mode, --props selects attributes, --where uses the same server-side condition syntax as count, and --sort accepts comma-separated attributes with - for descending order. View mode accepts --view <name-or-id> with optional --scope any|system|personal; --where composes with the view FetchXML as additional AND conditions. Use --fetchxml or --fetchxml-file for advanced FetchXML such as joins or nested filters. Resource list/export commands use --props a,b for exact columns, --props +extra for defaults plus extras, and --props * for all readable columns.

d365 data delete supports either --id <guid> for one record or guarded --where <conditions> for bulk deletion. Bulk delete first retrieves matching records up to --max-records + 1 using server-side FetchXML; if the match count exceeds --max-records (default 1000), no records are deleted. Use --dry-run with optional --props to preview matched records. Live --where deletes always require an interactive confirmation prompt, and --yes is intentionally ignored for this mode.

create and update accept --values <json>, --values-file <path>, and comma-separated --set pairs. When more than one input source is supplied, values are merged in this order: file, inline JSON, then --set. JSON primitives map to normal Dataverse values; typed JSON objects support option, money, lookup, guid, datetime, and null, for example:

{
  "name": "Sample",
  "statuscode": { "type": "option", "value": 1 },
  "parentcustomerid": { "type": "lookup", "entity": "account", "id": "00000000-0000-0000-0000-000000000000" },
  "description": { "type": "null" }
}

For shell input, typed --set values use name:type=value, such as revenue:money=123.45 or parentcustomerid:lookup=account/<guid>. Live create, update, and single-record delete operations ask for confirmation unless --yes is supplied; --dry-run validates and previews the operation without changing Dataverse.

Authentication and Configuration

  • Descriptor-backed tools expose a guided setup command that creates/selects a shared profile and stores non-secret target settings. For example: acs setup, d365 setup, service-bus setup --profile dev --subscription <subscription-id> --yes, and az-cost setup.
  • Azure Container Apps and Azure Cost commands use Azure SDK clients with DefaultAzureCredential. Configure credentials through the standard Azure Identity mechanisms for your runtime environment.
  • Dynamics 365 and Dataverse commands accept a direct connection string with --conn, or a Key Vault secret with --kv and --secret. --kv can also be a fully qualified Key Vault secret URI. When neither is provided, pass --url <dataverse-environment-url> to authenticate with non-interactive DefaultAzureCredential using existing Azure Identity sign-ins such as az login, Visual Studio, Azure PowerShell, Azure Developer CLI, managed identity, or environment credentials. For local user login, run d365 login --url <dataverse-environment-url> once; later --url commands silently reuse the cached Dataverse user token.
  • Service Bus list and dead-letter commands accept a Service Bus connection string with --conn.
  • Service Bus copy commands use Azure Resource Manager with DefaultAzureCredential. Configure credentials through Azure Identity mechanisms such as az login, Visual Studio, Azure PowerShell, Azure Developer CLI, managed identity, or environment credentials. service-bus namespaces copy duplicates safe namespace settings and topology without messages; service-bus queues copy copies queue definitions and queue authorization rules into an existing target namespace.
  • The base stash commands can store reusable values locally for token preprocessing.

Publishing

NuGet package planning, validation, and publishing are handled by tools/release-packages.ps1.

See the NuGet release automation guide for dry runs, package validation, release tags, and GitHub Actions publishing.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on Reimaginate.CLI.Base:

Package Downloads
Reimaginate.CLI.Microsoft.ACS.Tools

Azure Container Apps command handlers for deploying, exporting, replicating, inspecting, and updating container apps and jobs from Reimaginate CLI.

Reimaginate.CLI.Microsoft.CRM.Tools

Dynamics 365 and Dataverse command handlers for listing, exporting, comparing, and updating CRM assets from Reimaginate CLI.

Reimaginate.Orchestrator.Common

Core Orchestrator runtime services, workflow execution, persistence helpers, and transitive workflow action generation support.

Reimaginate.Orchestrator.CommandLine

Reusable command-line commands and hosting extensions for Orchestrator workflow hosts.

Reimaginate.CLI.Microsoft.ServiceBus.Tools

Azure Service Bus command handlers for listing queues, resubmitting dead-letter messages, and copying namespace or queue topology from Reimaginate CLI.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-rc.88 60 6/22/2026
1.0.0-rc.87 60 6/22/2026
1.0.0-rc.86 79 6/22/2026
1.0.0-rc.85 60 6/22/2026
1.0.0-rc.84 59 6/22/2026
1.0.0-rc.83 61 6/22/2026
1.0.0-rc.82 72 6/21/2026
1.0.0-rc.81 70 6/21/2026
1.0.0-rc.80 58 6/21/2026
1.0.0-rc.79 73 6/21/2026
1.0.0-rc.78 66 6/21/2026
1.0.0-rc.77 68 6/21/2026
1.0.0-rc.76 64 6/21/2026
1.0.0-rc.75 64 6/21/2026
1.0.0-rc.74 70 6/21/2026
1.0.0-rc.73 66 6/21/2026
1.0.0-rc.72 73 6/21/2026
1.0.0-rc.71 65 6/21/2026
1.0.0-rc.70 72 6/21/2026
1.0.0-rc.69 185 6/14/2026
Loading failed