Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
"source": "./plugins/dataverse-customization-xml",
"description": "Schema-validated hand-editing of Dataverse customization XML (ribbon, sitemap, forms, FetchXML, charts and more) against the official Microsoft XSDs — standalone PowerShell validator plus live lemminx LSP diagnostics.",
"category": "development"
},
{
"name": "power-automate-cloud-flow",
"source": "./plugins/power-automate-cloud-flow",
"description": "Schema-validated hand-editing of unpacked Power Automate solution cloud-flow JSON (Workflows/*.json) against a bundled clientdata/WDL wrapper schema, with live vscode-json-language-server LSP diagnostics.",
"category": "development"
}
]
}
13 changes: 12 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,23 @@ jobs:
- name: End-to-end setup (fetch schemas + lemminx, stamp paths, self-check)
run: ./plugins/dataverse-customization-xml/scripts/Install-Plugin.ps1

# node_modules is not committed; npm ci restores it deterministically from the lockfile.
# Caching it makes the setup step's npm ci a near-no-op on cache hit.
- name: Cache flow LSP node_modules
uses: actions/cache@v4
with:
path: plugins/power-automate-cloud-flow/node_modules
key: flow-lsp-${{ runner.os }}-${{ hashFiles('plugins/power-automate-cloud-flow/package-lock.json') }}

- name: End-to-end setup (install JSON language server, stamp paths, LSP self-check)
run: ./plugins/power-automate-cloud-flow/scripts/Install-Plugin.ps1

# Version bounds on both modules are deliberate: a new major on the PowerShell Gallery
# should not be able to turn CI red without a change in this repo.
- name: Pester tests
run: |
Install-Module Pester -MinimumVersion 5.5.0 -MaximumVersion 6.99.99 -Force -SkipPublisherCheck
Invoke-Pester plugins/dataverse-customization-xml/tests -CI
Invoke-Pester plugins -CI

- name: PSScriptAnalyzer
run: |
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## Unreleased

- New plugin `power-automate-cloud-flow`: live schema validation of unpacked Power Automate
solution cloud-flow JSON (`Workflows/*.json`).
- Bundled draft-07 clientdata/WDL wrapper schema (structure only — connector `inputs` left
loose by design, since `OpenApiConnection` isn't in the public Logic Apps schema).
- Live `vscode-json-language-server` LSP diagnostics for Claude Code (and VS Code via
`json.schemas`); the server is `npm ci`-installed at setup, pinned in `package-lock.json`.
- One-shot `Install-Plugin.ps1` whose self-check drives the real LSP end-to-end
(`scripts/lsp-smoke.mjs`) and asserts the schema fires; `/power-automate-cloud-flow:setup`.
- Headless/CI structure checks via PowerShell's built-in `Test-Json` (no bespoke validator).
- Semantic linting (runAfter / connectionName resolution, hard-coded values) stays in the
`power-automate-flow-dev` skill; this plugin is the shape layer.

## 1.0.1 — 2026-07-16

- Fix: installer no longer reports failure to CI-style hosts after a successful self-check
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ Update later with `/plugin marketplace update dataverse-agent-plugins` then
| Plugin | What it does |
|--------|--------------|
| [dataverse-customization-xml](plugins/dataverse-customization-xml/) | Schema-validated hand-editing of Dataverse customization XML (ribbon, sitemap, forms, FetchXML, charts, ISV config and more) against the official Microsoft XSDs. Standalone PowerShell validator + live lemminx LSP diagnostics. Also usable from [Codex](plugins/dataverse-customization-xml/docs/codex.md), [VS Code with no agent](plugins/dataverse-customization-xml/docs/vscode.md), and CI. |
| [power-automate-cloud-flow](plugins/power-automate-cloud-flow/) | Schema-validated hand-editing of unpacked Power Automate solution cloud-flow JSON (`Workflows/*.json`) against a bundled clientdata/WDL wrapper schema. Live `vscode-json-language-server` LSP diagnostics; headless structure checks via built-in `Test-Json`. Also usable from [Codex](plugins/power-automate-cloud-flow/docs/codex.md), [VS Code with no agent](plugins/power-automate-cloud-flow/docs/vscode.md), and CI. |

## Requirements

PowerShell 7+ (`pwsh`) on Windows, macOS or Linux. Plugins fetch what else they need at
setup (Microsoft XSDs, lemminx binary) — nothing bulky or third-party is committed here.
PowerShell 7+ (`pwsh`) on Windows, macOS or Linux. The `power-automate-cloud-flow` plugin also
needs Node.js (for its `npm`-installed JSON language server). Plugins fetch what else they need
at setup (Microsoft XSDs, lemminx binary, the JSON language server) — nothing bulky or
third-party is committed here.

## License

Expand Down
11 changes: 11 additions & 0 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

## Docs

### dataverse-customization-xml

- [Repo README](README.md): marketplace overview, install, requirements
- [Plugin README](plugins/dataverse-customization-xml/README.md): full setup for every consumer type
- [SKILL.md](plugins/dataverse-customization-xml/SKILL.md): the agent skill — validation workflow, root-element→schema table, ribbon-button recipe, gotchas
Expand All @@ -17,6 +19,15 @@
- [Debugging](plugins/dataverse-customization-xml/docs/debugging.md): setup failures, missing diagnostics, false positives
- [Schema source](plugins/dataverse-customization-xml/schemas/SOURCE.md): where the Microsoft XSDs come from, refresh procedure

### power-automate-cloud-flow

- [Plugin README](plugins/power-automate-cloud-flow/README.md): install + setup for every consumer type
- [SKILL.md](plugins/power-automate-cloud-flow/SKILL.md): the shape-vs-semantics split, what attaches, gotchas
- [Codex guide](plugins/power-automate-cloud-flow/docs/codex.md): the `Test-Json` validation loop from non-Claude agents
- [VS Code guide](plugins/power-automate-cloud-flow/docs/vscode.md): editor-only setup, CI usage
- [Debugging](plugins/power-automate-cloud-flow/docs/debugging.md): setup failures, missing diagnostics
- [Schema source](plugins/power-automate-cloud-flow/schemas/SOURCE.md): what the wrapper schema validates and why

## Optional

- [Design spec](docs/specs/2026-07-15-dataverse-agent-plugins-repo-design.md): why the repo is shaped this way
Expand Down
13 changes: 13 additions & 0 deletions plugins/power-automate-cloud-flow/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
"name": "power-automate-cloud-flow",
"version": "1.0.0",
"description": "Schema-validated hand-editing of unpacked Power Automate solution cloud-flow JSON (Workflows/*.json) against a bundled clientdata/WDL wrapper schema, with live vscode-json-language-server LSP diagnostics.",
"author": {
"name": "Connor Parsons"
},
"homepage": "https://github.com/Cordedmink2/dataverse-agent-plugins",
"skills": [
"./"
]
}
2 changes: 2 additions & 0 deletions plugins/power-automate-cloud-flow/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Installed at setup by scripts/Install-JsonLanguageServer.ps1 (npm ci from the pinned package-lock.json)
node_modules/
52 changes: 52 additions & 0 deletions plugins/power-automate-cloud-flow/.lsp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"json": {
"command": "node",
"args": [
"${CLAUDE_PLUGIN_ROOT}/node_modules/vscode-langservers-extracted/lib/json-language-server/node/jsonServerMain.js",
"--stdio"
],
"extensionToLanguage": {
".json": "json"
},
"initializationOptions": {
"provideFormatter": true,
"handledSchemaProtocols": [
"file"
],
"settings": {
"json": {
"validate": {
"enable": true
},
"schemas": [
{
"fileMatch": [
"**/Workflows/*.json",
"**/Workflows/**/*.json",
"**/*.flow.json"
],
"url": "schemas/cloud-flow-clientdata.schema.json"
}
]
}
}
},
"settings": {
"json": {
"validate": {
"enable": true
},
"schemas": [
{
"fileMatch": [
"**/Workflows/*.json",
"**/Workflows/**/*.json",
"**/*.flow.json"
],
"url": "schemas/cloud-flow-clientdata.schema.json"
}
]
}
}
}
}
102 changes: 102 additions & 0 deletions plugins/power-automate-cloud-flow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# power-automate-cloud-flow

A Claude Code plugin for **live schema validation of unpacked Power Automate solution cloud-flow
JSON** — the `Workflows/<name>-<guid>.json` files `pac solution unpack` produces (the flow
clientdata: a WDL `definition` plus its `connectionReferences`). Malformed structure shows up as
editor diagnostics *before* `pac solution import`.

This is the **shape** layer. Cross-node semantics (`runAfter` targets a real sibling, `connectionName`
resolves, hard-coded env values) and the export/pack/import round-trip live in the
`power-automate-flow-dev` skill. See `SKILL.md` for the split.

## The validation layer

**LSP (live)** — `vscode-json-language-server` (from `vscode-langservers-extracted`) pushes
diagnostics as you edit, using the bundled draft-07 wrapper schema. Wired for Claude Code (this
plugin's `.lsp.json`) and usable in VS Code (built-in JSON language features via `json.schemas`).

There is no separate CLI validator script: for headless/CI structure checks, PowerShell's built-in
`Test-Json -SchemaFile schemas/cloud-flow-clientdata.schema.json` validates against the same schema
the LSP loads.

## Install (Claude Code)

```
/plugin marketplace add Cordedmink2/dataverse-agent-plugins
/plugin install power-automate-cloud-flow@dataverse-agent-plugins
/power-automate-cloud-flow:setup
```

The setup command installs the pinned JSON language server (`npm ci`), stamps this machine's
absolute schema path into `.lsp.json`, and runs an end-to-end self-check that drives the real server.
It requires PowerShell 7+ (`pwsh`) and Node.js (for `npm`/`node`). Then run `/reload-plugins` (or
restart the session) so the LSP starts with the stamped path.

## Setup script directly (non-Claude consumers)

The slash command is a thin wrapper around one idempotent script:

```
pwsh scripts/Install-Plugin.ps1 [-UpdateVSCode]
```

- `-UpdateVSCode` also writes the `json.schemas` association into your VS Code user settings.

Run this one script rather than the individual `Install-*`/`Set-*` scripts — a partial manual setup
can leave a running server pointing at a broken relative schema path.

## What's inside

| Path | Purpose |
|------|---------|
| `SKILL.md` | The skill: the shape-vs-semantics split, what attaches, gotchas |
| `commands/setup.md` | The `/power-automate-cloud-flow:setup` slash command |
| `scripts/Install-Plugin.ps1` | One-shot setup: server install + path stamping + self-check |
| `scripts/Install-JsonLanguageServer.ps1` | `npm ci` the pinned JSON language server into `node_modules/` |
| `scripts/Set-LspSchemaPaths.ps1` | Stamp this machine's absolute schema `file://` URI into `.lsp.json` (+ VS Code) |
| `scripts/lsp-smoke.mjs` | End-to-end LSP health check (drives the server, asserts the schema fires) |
| `.lsp.json` | Registers the JSON server with Claude Code, with the flow `json.schemas` association |
| `package.json` / `package-lock.json` | Pin the JSON language server version |
| `schemas/cloud-flow-clientdata.schema.json` | The bundled draft-07 wrapper schema |
| `schemas/SOURCE.md` | What the schema validates, what it deliberately doesn't, how to refresh |
| `tests/` | Pester suite (config parity + fixture validation) + valid/invalid fixtures |
| `docs/` | Guides for Codex, VS Code-only, and debugging |

The JSON language server (`node_modules/`) is **installed at setup, not shipped**. The schema is
hand-maintained and committed.

## Updating

```
/plugin marketplace update dataverse-agent-plugins
/plugin update power-automate-cloud-flow@dataverse-agent-plugins
/power-automate-cloud-flow:setup
```

Re-run setup after every update — it re-installs the pinned server and re-stamps the schema path (see
`docs/debugging.md` for why).

## Other consumers

- **Codex / any non-Claude agent** — see [`docs/codex.md`](docs/codex.md).
- **VS Code only (no agent)** — see [`docs/vscode.md`](docs/vscode.md).
- **CI / pre-commit** — validate structure with `Test-Json`:
`Get-Content <flow>.json -Raw | Test-Json -SchemaFile schemas/cloud-flow-clientdata.schema.json`.

Something not working? [`docs/debugging.md`](docs/debugging.md).

## Known caveats

- **The wrapper is loose on action inputs by design** — `OpenApiConnection` connector actions aren't
in Microsoft's public Logic Apps schema, so a strict `$ref` would produce more false positives than
real findings. Structure is validated; `pac solution check` / a successful import is authoritative.
- **`${CLAUDE_PLUGIN_ROOT}` is only substituted in `.lsp.json` `command`/`args`**, not in nested
`settings` — hence the absolute-path fixup script.

## License

MIT (see the repo root `LICENSE`). The bundled schema is original to this repo. The JSON language
server is installed from npm at setup and remains under its own license.

See `SKILL.md` for the shape-vs-semantics layering and how this plugin pairs with the
`power-automate-flow-dev` skill.
76 changes: 76 additions & 0 deletions plugins/power-automate-cloud-flow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
name: power-automate-cloud-flow
description: >-
Live schema validation of unpacked Power Automate solution cloud-flow JSON while you hand-edit it.
Use when editing a pac-unpacked solution's Workflows/*.json (the flow clientdata: WDL definition +
connectionReferences) and you want malformed structure to show up as editor diagnostics before
pack/import. Provides a bundled draft-07 wrapper schema and a vscode-json-language-server LSP that
attaches to Workflows/*.json and *.flow.json. This is the SHAPE layer only — cross-node semantic
checks (runAfter targets a real sibling, connectionName resolves, hard-coded env values) and the
export/pack/import round-trip live in the power-automate-flow-dev skill.
---

# Power Automate cloud-flow JSON (schema-validated)

A solution cloud flow, once `pac solution unpack`ed, is `Workflows/<name>-<guid>.json`: the flow's
**clientdata** — a Workflow Definition Language (WDL) `definition` plus its `connectionReferences`.
This plugin makes malformed edits to that file **surface as live LSP diagnostics** while you type,
instead of failing at `pac solution import`.

It is one layer of a two-layer story — do not confuse them:

| Layer | What it checks | Where |
|-------|----------------|-------|
| **Shape (this plugin)** | JSON well-formedness + the clientdata/WDL wrapper structure: `properties.definition` present, `definition` has `$schema`/`triggers`/`actions`, `runAfter` statuses are the WDL enum. Live, in-editor. | `schemas/cloud-flow-clientdata.schema.json` via `vscode-json-language-server` (`.lsp.json`) |
| **Semantics (the `power-automate-flow-dev` skill)** | Cross-node rules JSON Schema *cannot* express: `runAfter` naming a real sibling, `connectionName` resolving to a declared connection reference, child-invoker connections, hard-coded environment values, condition rows. Plus the export → unpack → edit → pack → import → verify round-trip. | that skill's `flow-lint.ps1` |

**Rule of thumb:** the LSP catches "this isn't a well-formed flow file." `flow-lint.ps1` catches "this
is well-formed but will import Off / route to the wrong place." Run both before pack/import.

## Setup (once per machine)

The JSON language server is a Node package fetched via npm; it is not committed. Run:

```
/power-automate-cloud-flow:setup
```

or directly `pwsh "${CLAUDE_PLUGIN_ROOT}/scripts/Install-Plugin.ps1"`. That installs the pinned server
(`npm ci`), stamps the machine-local absolute schema path into `.lsp.json` (because
`${CLAUDE_PLUGIN_ROOT}` is not substituted inside LSP `settings`), and runs an end-to-end self-check
that drives the real server and confirms the schema fires. Then `/reload-plugins`.

## What attaches to what

The schema associates (see `.lsp.json`) with:

- `**/Workflows/*.json` and `**/Workflows/**/*.json` — unpacked solution cloud flows
- `**/*.flow.json` — a convenience convention for a standalone flow file

It deliberately does **not** claim every `*.json` in the workspace.

## Subagents / headless contexts

LSP diagnostics only auto-push in the **main interactive session**. A spawned subagent, a workflow
step, or any non-main-session context does NOT receive them. In those contexts validate structure
explicitly with PowerShell's built-in `Test-Json`:

```
Get-Content <flow>.json -Raw | Test-Json -SchemaFile "${CLAUDE_PLUGIN_ROOT}/schemas/cloud-flow-clientdata.schema.json"
```

(and run the `power-automate-flow-dev` skill's `flow-lint.ps1` for the semantic layer).

## Gotchas

- **The wrapper is intentionally loose on action inputs.** Power Automate connector actions
(`OpenApiConnection`) are not in Microsoft's public Logic Apps schema, so a strict `$ref` would
drown real errors in false positives. `inputs` is left untyped; structure is what's validated.
`pac solution check` / a successful import remains the authoritative gate.
- **`${CLAUDE_PLUGIN_ROOT}` is not substituted** inside `.lsp.json` `initializationOptions`/`settings`
— only in `command`/`args`. The schema `url` there is an absolute `file://` URI. On a new machine
(or after a plugin update / move), re-run `/power-automate-cloud-flow:setup` — or
`scripts/Set-LspSchemaPaths.ps1` alone — to re-stamp it.
- **The JSON server validates a document only after answering its `workspace/configuration` pull.**
Claude Code and VS Code both handle that; a bare LSP client must too (see `scripts/lsp-smoke.mjs`
for a reference client).
14 changes: 14 additions & 0 deletions plugins/power-automate-cloud-flow/commands/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: Install the JSON language server + stamp the machine-local schema path (run once after install/update)
---

Run this plugin's setup script and report the result:

1. Ask the user whether they also want VS Code's JSON schema association configured
(adds `json.schemas` to their VS Code user settings).
2. Run: `pwsh "${CLAUDE_PLUGIN_ROOT}/scripts/Install-Plugin.ps1"` — append ` -UpdateVSCode`
if they said yes.
3. Show the self-check outcome. If setup failed, show the error verbatim and point the user
at `${CLAUDE_PLUGIN_ROOT}/docs/debugging.md`.
4. If setup succeeded, remind the user to run `/reload-plugins` so the JSON LSP starts with the
stamped schema path.
28 changes: 28 additions & 0 deletions plugins/power-automate-cloud-flow/docs/codex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Using this plugin with Codex (or any non-Claude agent)

LSP diagnostics only push into Claude Code's main session, so every other agent must validate
explicitly after each edit. There is no bespoke validator script — PowerShell 7's built-in
`Test-Json` validates against the same bundled schema the LSP loads.

## Setup

1. Clone the repo. No server install is needed for the `Test-Json` path (that's only for the LSP),
but PowerShell 7+ (`pwsh`) is required.

2. Make the skill discoverable. Codex reads `AGENTS.md` — add:

> When editing an unpacked Power Automate solution cloud flow (`Workflows/*.json` — the flow
> clientdata: WDL `definition` + `connectionReferences`), follow
> `<clone-path>/plugins/power-automate-cloud-flow/SKILL.md`, and after EVERY edit run:
> `Get-Content <file> -Raw | Test-Json -SchemaFile <clone-path>/plugins/power-automate-cloud-flow/schemas/cloud-flow-clientdata.schema.json`
> A schema error means the edit is structurally invalid; fix before pack/import. Then run the
> `power-automate-flow-dev` skill's `flow-lint.ps1` for the semantic layer (runAfter /
> connectionName resolution, hard-coded values).

3. If your Codex setup supports skill folders, point it at `plugins/power-automate-cloud-flow/`
directly — `SKILL.md` has standard frontmatter.

## The loop

edit → `Test-Json -SchemaFile <schema> <file>` (structure) → `flow-lint.ps1` (semantics) → fix until
clean → `pac solution pack` → import.
Loading
Loading