Reimaginate.CLI.Base
1.0.0-rc.88
dotnet add package Reimaginate.CLI.Base --version 1.0.0-rc.88
NuGet\Install-Package Reimaginate.CLI.Base -Version 1.0.0-rc.88
<PackageReference Include="Reimaginate.CLI.Base" Version="1.0.0-rc.88" />
<PackageVersion Include="Reimaginate.CLI.Base" Version="1.0.0-rc.88" />
<PackageReference Include="Reimaginate.CLI.Base" />
paket add Reimaginate.CLI.Base --version 1.0.0-rc.88
#r "nuget: Reimaginate.CLI.Base, 1.0.0-rc.88"
#:package Reimaginate.CLI.Base@1.0.0-rc.88
#addin nuget:?package=Reimaginate.CLI.Base&version=1.0.0-rc.88&prerelease
#tool nuget:?package=Reimaginate.CLI.Base&version=1.0.0-rc.88&prerelease
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
setupcommand 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, andaz-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--kvand--secret.--kvcan also be a fully qualified Key Vault secret URI. When neither is provided, pass--url <dataverse-environment-url>to authenticate with non-interactiveDefaultAzureCredentialusing existing Azure Identity sign-ins such asaz login, Visual Studio, Azure PowerShell, Azure Developer CLI, managed identity, or environment credentials. For local user login, rund365 login --url <dataverse-environment-url>once; later--urlcommands 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 asaz login, Visual Studio, Azure PowerShell, Azure Developer CLI, managed identity, or environment credentials.service-bus namespaces copyduplicates safe namespace settings and topology without messages;service-bus queues copycopies queue definitions and queue authorization rules into an existing target namespace. - The base
stashcommands 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 | Versions 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. |
-
net9.0
- Azure.Identity (>= 1.21.0)
- Azure.Security.KeyVault.Secrets (>= 4.11.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.8)
- Microsoft.Extensions.Http (>= 9.0.8)
- NuGet.Frameworks (>= 6.14.3)
- NuGet.Packaging (>= 6.14.3)
- NuGet.Protocol (>= 6.14.3)
- NuGet.Versioning (>= 6.14.3)
- Reimaginate.Mediator.Abstractions (>= 1.3.0-rc.8)
- Spectre.Console (>= 0.55.2)
- Spectre.Console.Cli (>= 0.55.0)
- System.CommandLine (>= 2.0.8)
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 |