Skip to content

Add /setup-prerequisites skill to the power-pages plugin - #319

Open
Priyanshu Agrawal (priyanshu92) wants to merge 5 commits into
mainfrom
users/priyanshu92/crispy-guacamole
Open

Add /setup-prerequisites skill to the power-pages plugin#319
Priyanshu Agrawal (priyanshu92) wants to merge 5 commits into
mainfrom
users/priyanshu92/crispy-guacamole

Conversation

@priyanshu92

@priyanshu92 Priyanshu Agrawal (priyanshu92) commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Why

Installing the power-pages plugin from the marketplace copies the skill files and nothing else. Only the repo-root scripts/install.js sets up the CLIs, and it never runs on the marketplace path, so a user can land in the plugin with no PAC CLI, no Azure CLI, no .NET SDK, and no sign-in. Today they find out one skill at a time, as "pac is not recognized".

This adds /setup-prerequisites to close that gap.

What it does

Checks Node.js, the .NET SDK, the Power Platform CLI, and the Azure CLI, plus both CLI sign-ins. Asks before each install, one tool at a time, then signs in. It stops before Dataverse environment selection - picking an environment belongs to whichever skill needs one.

Two scripts do the deterministic work, with the SKILL.md orchestrating the asking:

  • detect-prerequisites.js probes read-only and emits a JSON status plus an actions list of { tool, kind }. It also checks NuGet for a newer PAC CLI and warns when the two CLIs are signed into different tenants, which otherwise surfaces later as confusing 401s.
  • install-prerequisite.js owns the per-platform install command: winget on Windows, Homebrew on macOS, dotnet tool install for PAC everywhere. --dry-run gives the workflow the exact command to show at the consent prompt, so the approval and the execution can't drift.

A failed or unsupported install never stops the run. Everything outstanding lands in the final summary with a manual command.

Worth a careful look

Windows az.cmd. The Azure CLI ships only as a batch shim on Windows, and Node refuses to spawn a .cmd without a shell (EINVAL since 18.20.2/20.12.2). Probing az directly reports an installed Azure CLI as missing, which then prompts the user to reinstall a CLI they already have. Windows probes now route through cmd.exe /c via buildProbeInvocation, still passing args as an array so nothing is concatenated into a shell string. install-prerequisite.js is unaffected - it only ever spawns winget, brew, and dotnet, all real executables.

The fresh-machine ordering case. On a machine with neither the .NET SDK nor PAC, installing the SDK does not unblock the PAC install in the same session: the installer writes PATH for future processes, while every script here runs under a shell that started earlier. Phase 2 tells the agent to expect the unsupported result and route the user to a terminal restart, rather than reporting it as a platform limitation. The script's own reason string says the same thing.

Scope deliberately left out. disable-model-invocation: true keeps the agent from firing this on its own mid-task; it stays reachable by name, so another skill can still delegate to it. None of the existing 31 skills do yet - wiring them to hand off on a missing tool would mean touching every one of them, so it is left for a follow-up.

Verification

34 new tests, full power-pages suite passing at 1343, lint-skills-alm.js clean, and all repo-level validators pass. Both scripts were run live on macOS against a real signed-in PAC and Azure CLI.

Two review passes caught three real bugs before this landed: the Windows az.cmd case, a --dry-run invocation that omitted --update and so displayed the wrong command at the PAC update prompt, and the misleading same-session SDK guidance. All three are fixed with test coverage.

Docs updated: plugin README (prerequisites note, skill entry, count 31 -> 32, workflow step 0), AGENTS.md skill tree, approval-gates catalog section 6.31, and the skill-tracking mapping table.

Installing the plugin from the marketplace copies the skill files and
nothing else, so a marketplace user can arrive with none of the command
line tools the skills call. Only the repo-root install.js sets those up,
and it never runs on that path.

The skill checks Node.js, the .NET SDK, the PAC CLI, and the Azure CLI,
asks per missing tool before installing it, and signs both CLIs in. It
stops before Dataverse environment selection.

- detect-prerequisites.js probes read-only and emits a JSON status plus
  an actions list. Windows probes route through cmd.exe /c because the
  Azure CLI ships only as az.cmd, which Node refuses to spawn directly.
- install-prerequisite.js owns the per-platform install command: winget
  on Windows, Homebrew on macOS, dotnet tool for PAC everywhere. Linux
  falls back to printed commands.
- A failed or unsupported install does not stop the run; everything
  outstanding lands in the final summary with a manual command.
- Two consent gates cataloged in references/approval-gates.md, one per
  install and one per sign-in.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The skill is something the user reaches for deliberately when their
machine is not set up, not something the agent should fire on its own -
an autonomous invocation would start installing tools mid-task.

Disabling model invocation also retires the trigger phrases from the
description, which only served autonomous matching, so it is now a
human-facing one-liner.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 27, 2026 18:37
@priyanshu92
Priyanshu Agrawal (priyanshu92) requested a review from a team as a code owner July 27, 2026 18:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new /setup-prerequisites skill to the power-pages plugin so marketplace installs can self-check and (with explicit consent) install required CLIs and complete pac/az sign-in before other skills run.

Changes:

  • Introduces a new setup-prerequisites skill workflow plus two supporting Node scripts: a read-only detector and a per-tool installer (with --dry-run support for consent prompts).
  • Adds unit tests covering prerequisite detection/parsing and install plan resolution across platforms.
  • Updates plugin documentation and references (skill catalog, approval gates, tracking mapping, and skill tree).
Show a summary per file
File Description
plugins/power-pages/skills/setup-prerequisites/SKILL.md Adds the user-invoked workflow that orchestrates detect → consented installs → sign-in → summary.
plugins/power-pages/skills/setup-prerequisites/scripts/install-prerequisite.js Implements per-platform install/update command resolution and execution for one tool per invocation.
plugins/power-pages/skills/setup-prerequisites/scripts/detect-prerequisites.js Implements read-only probing (versions/auth) + action list generation, including Windows az.cmd probing behavior.
plugins/power-pages/scripts/tests/install-prerequisite.test.js Adds unit coverage for install plan resolution and argument parsing.
plugins/power-pages/scripts/tests/detect-prerequisites.test.js Adds unit coverage for probe invocation, parsers, version comparison, and action list logic.
plugins/power-pages/references/skill-tracking-reference.md Registers setup-prerequisites in the skill tracking mapping table.
plugins/power-pages/references/approval-gates.md Documents the two new consent gates for installs and sign-ins.
plugins/power-pages/README.md Documents marketplace prerequisite setup and adds the new skill to the public skill list.
plugins/power-pages/AGENTS.md Updates the skill tree to include the new skill and its scripts.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread plugins/power-pages/scripts/tests/detect-prerequisites.test.js Outdated
Git is a real dependency, not an assumption: 13 skills commit after each
milestone, and check-version.js shells out to git rev-parse and git fetch.
Without it those steps fail outright rather than degrade, so a machine
missing git hits the same wall the skill exists to prevent.

Detection reads `git --version`, which the Apple-shipped and Windows
builds both suffix ("2.39.5 (Apple Git-154)", "2.51.0.windows.1"), so the
parser stops at the numeric version. Install goes through winget Git.Git
on Windows and brew git on macOS, with xcode-select and apt among the
manual fallbacks.

Git is ordered ahead of the .NET SDK in the action list so the tool the
most skills depend on is offered first.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 29, 2026 07:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Comments suppressed due to low confidence (2)

plugins/power-pages/skills/setup-prerequisites/scripts/install-prerequisite.js:101

  • --update is documented as only supported for pac, but for other tools the flag is silently ignored and the plan still uses an install command (e.g., winget install). This makes the CLI contract misleading and could cause unintended behavior if a caller passes --update for a non-pac tool. Consider explicitly rejecting --update for unsupported tools with a clear reason.
function resolveInstallPlan({ tool, platform, update = false, commandExists = hasCommand }) {
  const manual = MANUAL_INSTRUCTIONS[tool] || [];

plugins/power-pages/skills/setup-prerequisites/scripts/detect-prerequisites.js:308

  • azAuth is derived only from az account show, which can fail for users who sign in via az login --allow-no-subscriptions (no default subscription). In that case this script will keep reporting Azure CLI as signed out, causing /setup-prerequisites to repeatedly prompt for sign-in even though the CLI is authenticated. Add a fallback probe (e.g., az account tenant list -o json) so subscription-less accounts are still treated as signed in.
  const pacAuth = parsePacAuthWho(pacVersion ? probe('pac', ['auth', 'who']) : null);
  const azAuth = parseAzAccountShow(
    azVersion ? probe('az', ['account', 'show', '-o', 'json']) : null
  );
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Low

/report-issue shells out to `gh issue create`, so a machine without gh
hits a dead end there. Unlike git, pac, and az, though, gh backs exactly
one skill - telling a user with a working Power Pages setup that they are
not ready would be noise. So gh actions carry `optional: true`, and the
ready verdict now ignores optional work rather than requiring an empty
action list.

Detecting gh auth turned out to be the tricky part. `gh auth status`
writes its whole report to stderr, and exits 1 when ANY configured host
fails - so a user logged in to github.com with a broken enterprise host
alongside it read as signed out. The probe now takes mergeStderr and
acceptNonZeroExit for that call and lets the parser judge.

The parser requires a github.com login specifically. An enterprise-only
login cannot file against microsoft/power-platform-skills, and treating
it as signed in would defer the failure to `gh issue create`.

probe() moved from execFileSync to spawnSync to reach the exit code and
stderr without relying on a thrown error. Behavior is unchanged for the
pac, az, dotnet, and git probes: a missing binary sets `error`, and a
non-zero exit still yields null unless the caller opts out.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 12:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (3)

plugins/power-pages/scripts/tests/detect-prerequisites.test.js:80

  • This test case has an inline assertion after the opening brace, which is inconsistent with surrounding tests and reduces readability. Split the assertion onto its own line.
test('parsePacVersion strips the build-metadata suffix', () => {  assert.equal(parsePacVersion(PAC_HELP), '1.51.1');
});

plugins/power-pages/skills/setup-prerequisites/scripts/detect-prerequisites.js:336

  • buildActions() can emit an action for { tool: 'node' }, but install-prerequisite.js does not support a node tool (TOOLS excludes it) and the workflow already states Node is present by construction. Keeping this branch is a footgun if buildActions() is reused with a fixture where node.available is false, because it would produce an unexecutable action.
function buildActions(status) {
  const actions = [];
  if (!status.node.available) actions.push({ tool: 'node', kind: 'install' });
  if (!status.git.available) actions.push({ tool: 'git', kind: 'install' });

plugins/power-pages/scripts/tests/install-prerequisite.test.js:58

  • This test case header has an inline statement after the opening brace, which hurts readability and makes diffs noisier. Split the const win = … onto its own line.
test('dotnet uses winget on Windows and Homebrew on macOS', () => {  const win = resolveInstallPlan({ tool: 'dotnet', platform: 'win32', commandExists: everythingPresent });
  assert.equal(win.command, 'winget');
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Reject --update for tools that have no update path. It previously fell
through to an install plan, which is worse than a no-op here: the skill
shows the dry-run command at its approval prompt and then runs the same
command for real, so a stray --update would have the user approve
`dotnet tool update` and get an install. Only pac is updatable; the rest
now come back `unsupported` with a reason naming the flag.

Also un-collapse two test bodies that ended up on the same line as their
opening brace. The reviewer caught one; the other was the same defect in
install-prerequisite.test.js.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 13:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (3)

plugins/power-pages/skills/setup-prerequisites/scripts/install-prerequisite.js:281

  • --help currently exits with code 1 when no tool is provided (because the exit code is keyed off args.tool), which makes node install-prerequisite.js --help look like a failure to callers/scripts. Prefer exiting 0 whenever --help is present, and reserve exit 1 for missing/invalid arguments without --help.
  1  No automated install path on this platform, or the install failed
`
    );
    process.exit(args.tool ? 0 : 1);
  }

plugins/power-pages/skills/setup-prerequisites/scripts/detect-prerequisites.js:338

  • buildActions() can emit { tool: 'node', kind: 'install' }, but /skills/setup-prerequisites/scripts/install-prerequisite.js does not support installing Node (and the workflow notes that if Node is missing, none of these scripts can run). Keeping node out of the actions list avoids an action the workflow cannot execute if this function is ever reused with a different status object.
function buildActions(status) {
  const actions = [];
  if (!status.node.available) actions.push({ tool: 'node', kind: 'install' });
  if (!status.git.available) actions.push({ tool: 'git', kind: 'install' });
  if (!status.dotnet.available) actions.push({ tool: 'dotnet', kind: 'install' });

plugins/power-pages/README.md:39

  • The prerequisites table now mentions installing PAC via dotnet tool install ..., but it still omits the .NET SDK itself. Since /setup-prerequisites explicitly checks/installs the .NET SDK (and PAC installs cannot work without it), the README prerequisites list should include .NET SDK so marketplace users don’t miss it.
| [Node.js](https://nodejs.org/) (LTS) | All skills | `winget install OpenJS.NodeJS.LTS` |
| [Git](https://git-scm.com/downloads) | Commits made by most skills | `winget install Git.Git` |
| [PAC CLI](https://learn.microsoft.com/power-platform/developer/cli/introduction) | Deploy, activate, data model | `dotnet tool install -g Microsoft.PowerApps.CLI.Tool` |
| [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) | Data model, sample data, activation | `winget install Microsoft.AzureCLI` |
| [GitHub CLI](https://github.com/cli/cli#installation) (optional) | `/report-issue` only | `winget install GitHub.cli` |
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants