You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add Actions type of resource which implements a single invoke operation but declares if it's supported for get, set, test, and/or export`. Input schema required if input taken. Optional output schema if output returned and differs from input schema.
Moved some of the common types from dscresource into new resource folder.
ResourceInvoke trait abstracts resources, actions, and adapters. This resulted in wide code changes which used to take a DscResource. Functions added to trait for common properties across these types and also as_dsc_resource() and as_action() to make it easier to use.
ManifestKind extended with as_action_manifest() and as_resource_manifest() to easily access their respective manifests.
Consolidated the different DiscoveryCache into a single type since they all implement ResourceInvoke which also caused lots of code change.
Other specific changes:
path and directory in dscresource, extension, and action are now Option
remove use of unstable feature on config.toml since it's now stable
add new DscResourceKind that encapulates DscResource and DscAction, this resulted in many changes that formally only expected a DscResource
add new dsc action list to list actions, did not implement dsc action invoke since expectation is apps use the server apis
add invoke_dsc_action(), list_dsc_actions(), and show_dsc_action() server APIs
add tests for new server apis and using actions in configuration
add test actions that also cover security context and versioning
command discovery looks separately for actions and caches them separately
instead of relying on resources cache empty empty to perform discovery, add a flag since there's now 2 types of resources to be discovered
This tool can execute arbitrary action commands, and neither the manifest nor the handler guarantees idempotency. Repeating a restart, notification, or other imperative action can produce additional effects, so advertising every invocation as idempotent gives MCP clients an incorrect retry contract. Mark the generic action tool as non-idempotent unless idempotency is explicitly guaranteed.
SchemaArgKind and ArgKind share definitions/commandArgs.action.json, although only the latter accepts JSON-input and what-if argument objects. Exporting both will fail the exporter's duplicate-path check and cannot publish their distinct contracts. Give schema-command arguments their own base name.
Skip metadata injection for schema-less action input
lib/dsc-lib/src/configure/mod.rs:292
For a no-input action with resource metadata, including metadata added by a copy loop, this helper injects _metadata into otherwise empty input. The action then rejects that input with SchemaNotAvailable. Skip metadata injection when an action has no input schema and no properties were supplied.
Reject native actions when require_adapter is specified
lib/dsc-lib/src/discovery/mod.rs:197
For an action, as_dsc_resource() returns None, so this condition falls through to true even when the filter specifies require_adapter. A configuration that pins an adapter can therefore select a native action that does not require that adapter, violating the filter contract used by filter_resources(). Reject non-resource candidates when an adapter requirement is present.
Populate DscResource.author from resource manifests
The new author field is accepted in resource manifests, but load_resource_manifest() never copies it into DscResource.author, which defaults to None. Consequently, dsc resource list reports a null author and show_dsc_resource omits it even when the manifest supplies one. Copy the field while constructing the discovered resource, as the action loader does.
Register action schemas in the explicit export list
xtask/src/schemas/export.rs:113
The explicit schema export list contains no action types, so schema generation never produces bundled/action/manifest.json, which the new fixtures reference. Deriving DscRepoSchema does not register these types automatically. Register the action manifest, output, and supporting schemas after resolving their conflicting export paths.
An arbitrary action is not guaranteed to be idempotent: this handler executes its command on every call without a convergence check, so repeating an action can repeat side effects. Advertising idempotent_hint = true incorrectly tells MCP clients that repeated invocations have no additional effect. Use false for this generic invocation tool unless idempotence is explicitly established for every action it can invoke.
The ManifestList branch of load_manifest_content ignores the new actions member, so an extension returning manifestContent: {"actions": [...]} silently loses those actions. Add condition evaluation and action loading to that branch, using a valid directory context for inline manifests.
Persist discovery readiness across manager requests
Each new DscManager creates a fresh CommandDiscovery with resources_discovered = false, so successive server requests rescan paths and rerun extension discovery and command-backed action schema providers despite the populated static cache. Keep readiness state at the cache's lifetime, or reuse the discovery instance, while preserving explicit refresh behavior.
This unconditional success accepts properties for schema-less actions even though invocation rejects every nonempty input string. It also lets add_metadata inject _metadata, causing a no-input action with even metadata: {} to fail with SchemaNotAvailable. Reject supplied input during validation and keep configuration metadata out of the payload, preserving an empty input string when properties are absent.
The new author field is never copied into the discovered DscResource, so dsc resource list reports a null author and show_dsc_resource omits it even when the manifest supplies one. Assign resource.author = manifest.author.clone() alongside the description in load_resource_manifest (lib/dsc-lib/src/discovery/command_discovery.rs:1094).
Do not advertise idempotence for action invocations
dsc/src/server/invoke_dsc_action.rs:44
Action invocation always executes the command, and the manifest provides no idempotency guarantee. Advertising idempotent_hint = true tells MCP clients that repeating a call has no additional effects, which is unsafe for actions such as restarting a service and can repeat disruptive side effects on retries. Set this hint to false unless the action explicitly guarantees idempotence.
Allow boolean schemas in show_dsc_action responses
dsc/src/server/show_dsc_action.rs:16
The manifest accepts boolean JSON Schemas, and get_schema preserves them, so show_dsc_action can return inputSchema: true or outputSchema: false. This response schema excludes both values, causing schema-validating MCP clients to reject an otherwise successful response. Allow booleans alongside objects and null.
Preserve adapter schema validation for action resources
dsc/src/subcommand.rs:532
validate_properties requires a local schema or manifest before it tries schema(). Resources returned by an adapter's list command, such as Adapted/One, have neither, so this unconditional call makes valid adapted configurations fail with a missing-manifest error; the previous ImplementedAs::Command guard skipped them. Preserve that behavior while including actions, or extend the helper to validate through the adapter-provided schema.
Unconditional validation now rejects adapter-enumerated resources such as Adapted/One, whose list payload has neither a schema nor a manifest (tools/dsctest/src/adapter.rs:62–72). validate_properties returns noManifest, so configurations that previously passed dsc config validate now fail. Preserve the command-implementation guard while explicitly including actions, unless adapter-aware validation is implemented first.
Treat null export output as zero exported instances
lib/dsc-lib/src/actions/dscaction.rs:168
A supported export action that succeeds without stdout returns Value::Null, which this code wraps as an exported instance. Configuration export then fails when add_resource_export_results_to_configuration tries to deserialize that null into a property map. Represent no output as zero exported instances rather than [null], and cover this configuration-export case.
The newly supported ResourceManifest.author is never copied into the discovered DscResource. Resource-list JSON and show_dsc_resource therefore still report a null/missing author even when the manifest supplies one. Copy manifest.author alongside the other manifest metadata.
Preserve descending version order in fallback merges
lib/dsc-lib/src/discovery/mod.rs:140
The fallback merge appends versions without preserving newest-first ordering. On one manager, looking up =1.0.0 and then =2.0.0 leaves [1.0.0, 2.0.0], so a subsequent unversioned or broad-range lookup selects the older cached version. Insert by descending version, as command_discovery::insert_resource does.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Unresolved validation, export, discovery-filtering, and action-fixture defects need correction before approval.
No open issues 🎉
4 previously missed issues
In code that hasn't changed since last review
Preserve adapted-resource validation while validating actions
dsc/src/subcommand.rs:532
Unconditional validation makes dsc config validate reject existing PowerShell-adapted resources: their list output has neither a manifest nor an embedded schema (adapters/powershell/psDscAdapter/powershell.resource.ps1:208–220), so validate_properties returns noManifest. Preserve the previous command-resource validation scope for ordinary resources while also validating actions.
Treat action exports with no stdout as empty results
lib/dsc-lib/src/actions/dscaction.rs:167
A supported export action that emits no stdout succeeds in invoke_action with Value::Null, but wrapping it here produces one null instance. add_resource_export_results_to_configuration then tries to deserialize that instance into a properties map and fails, so dsc config export fails after an otherwise successful action. Represent no output as an empty instance list, consistent with command-resource export.
After a resource lookup populates the shared cache, listing actions with a specific type filter returns every cached action because discovery exits early and this loop ignores the filter. Apply type_name_filter when copying cached actions so filtered results do not depend on whether discovery has already run.
Make no-input action fixture invokable and test invocation
tools/dsctest/dsctest.dsc.action.json:20
Test/Action2 rejects supplied input because it has no input schema, but omitting input runs dsctest action --input "", which fails JSON deserialization. Use the existing no-op command to make this no-input fixture invokable, and add a configuration or server invocation test rather than testing only its listing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Summary
Add
Actionstype of resource which implements a singleinvokeoperation but declares if it's supported forget,set,test, and/orexport`. Input schema required if input taken. Optional output schema if output returned and differs from input schema.Moved some of the common types from
dscresourceinto newresourcefolder.ResourceInvoketrait abstractsresources,actions, andadapters. This resulted in wide code changes which used to take aDscResource. Functions added to trait for common properties across these types and alsoas_dsc_resource()andas_action()to make it easier to use.ManifestKindextended withas_action_manifest()andas_resource_manifest()to easily access their respective manifests.Consolidated the different
DiscoveryCacheinto a single type since they all implementResourceInvokewhich also caused lots of code change.Other specific changes:
pathanddirectoryin dscresource, extension, and action are now OptionDscResourceKindthat encapulatesDscResourceandDscAction, this resulted in many changes that formally only expected aDscResourcedsc action listto list actions, did not implementdsc action invokesince expectation is apps use the server apisinvoke_dsc_action(),list_dsc_actions(), andshow_dsc_action()server APIsPR Context
Fix #1470