diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5e2eb80..80665cb 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -13,7 +13,7 @@ "name": "microsoft-managed-apps", "source": "./plugins/microsoft-managed-apps", "description": "[Preview] Create and manage Microsoft Managed Apps using the @microsoft/managed-apps-cli (ms) toolchain.", - "version": "2.0.2" + "version": "2.0.3" } ] } diff --git a/plugins/microsoft-managed-apps/.claude-plugin/plugin.json b/plugins/microsoft-managed-apps/.claude-plugin/plugin.json index dec4388..b292360 100644 --- a/plugins/microsoft-managed-apps/.claude-plugin/plugin.json +++ b/plugins/microsoft-managed-apps/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "microsoft-managed-apps", - "version": "2.0.2", + "version": "2.0.3", "description": "[Preview] Create and manage Microsoft Managed Apps using the @microsoft/managed-apps-cli (ms) toolchain.", "author": { "name": "Microsoft", diff --git a/plugins/microsoft-managed-apps/AGENTS.md b/plugins/microsoft-managed-apps/AGENTS.md index 29ad78a..10c8e02 100644 --- a/plugins/microsoft-managed-apps/AGENTS.md +++ b/plugins/microsoft-managed-apps/AGENTS.md @@ -26,7 +26,7 @@ This plugin uses a memory bank (`memory-bank.md`) to persist state across sessio | `shared/shared-instructions.md` | Meta file aggregating all cross-cutting concerns — every skill links to it. | | `shared/planning-policy.md` | When to enter plan mode and what to include in the plan. | | `shared/memory-bank.md` | Memory bank schema + read/update protocol. | -| `shared/development-standards.md` | Versioning, theme, CLI install pattern, build rules, TypeScript strict mode. | +| `shared/development-standards.md` | Theme, CLI install pattern, build rules, TypeScript strict mode. | | `shared/version-check.md` | Daily plugin-version check against the marketplace. | ### Adding new shared instructions diff --git a/plugins/microsoft-managed-apps/QUICKSTART.md b/plugins/microsoft-managed-apps/QUICKSTART.md index ab39381..f99f189 100644 --- a/plugins/microsoft-managed-apps/QUICKSTART.md +++ b/plugins/microsoft-managed-apps/QUICKSTART.md @@ -49,7 +49,7 @@ Your copilot will: 3. Run `ms app create` to scaffold the project. 4. Start `ms app dev` so you can play the app locally in the App Player. -If the folder is not empty, the skill will stop and ask you to switch to an empty folder (or explicitly confirm overwrite behavior). +If the folder is not empty, the skill will create the app in an inferred subfolder and tell you which folder it selected. If you run it from inside an existing Microsoft App, it creates the new app alongside that app instead of nested inside it. Nothing deploys to the cloud at this point — local dev only. diff --git a/plugins/microsoft-managed-apps/README.md b/plugins/microsoft-managed-apps/README.md index 2e35cad..e04f203 100644 --- a/plugins/microsoft-managed-apps/README.md +++ b/plugins/microsoft-managed-apps/README.md @@ -47,10 +47,10 @@ The `/create-app` skill handles the global install of `@microsoft/managed-apps-c ## Try it ``` -/create-app +/create-app ``` -The skill walks you through global tooling install, account selection, app scaffolding, and a local dev server you can hit in the App Player. Nothing deploys to the cloud unless you explicitly ask. +Describe the app in the command and the skill generates its name, plans the complete requested experience for your approval, scaffolds it, builds it, and starts a local dev server in the App Player. Nothing deploys to the cloud unless you explicitly ask. ## Telemetry diff --git a/plugins/microsoft-managed-apps/shared/connector-decision-guide.md b/plugins/microsoft-managed-apps/shared/connector-decision-guide.md index e98a570..a2e1a4f 100644 --- a/plugins/microsoft-managed-apps/shared/connector-decision-guide.md +++ b/plugins/microsoft-managed-apps/shared/connector-decision-guide.md @@ -160,7 +160,7 @@ Example: "Meeting Insights" app ## Connector Selection Checklist -When a user describes their app, ask these questions: +When a user describes their app, answer this checklist internally from the prompt and available discovery results. Ask the user only for a required value that cannot be inferred or discovered: 1. **Is the app primarily a SEARCH interface?** - If YES → recommend Work IQ diff --git a/plugins/microsoft-managed-apps/shared/memory-bank.md b/plugins/microsoft-managed-apps/shared/memory-bank.md index 7283939..332b70b 100644 --- a/plugins/microsoft-managed-apps/shared/memory-bank.md +++ b/plugins/microsoft-managed-apps/shared/memory-bank.md @@ -26,7 +26,7 @@ The memory bank is always stored at: `/memory-bank.md` 1. If the user has specified a project path, check `/memory-bank.md`. 2. If continuing from a previous skill in the same session, use the known project path. -3. If no path is known, ask the user for the project path. +3. If no path is known, discover likely project roots from the current workspace first. Ask for the project path only when multiple candidates remain ambiguous. ### Step 2: Read and Parse Context @@ -34,7 +34,7 @@ If the memory bank exists, extract: | Information | Purpose | | --------------------------------- | ------------------------------------------------------ | -| Project path, name, version | Know what you're working with | +| Project path, name | Know what you're working with | | Completed steps (checkboxes) | Skip steps already done | | User preferences | Don't re-ask answered questions | | Created resources | Know what data sources/connectors exist | @@ -43,7 +43,7 @@ If the memory bank exists, extract: ### Step 3: Resume or Continue -- **If the current skill's steps are already marked complete**: Ask if they want to modify, add more, or skip to next steps. +- **If the current skill's steps are already marked complete**: Infer the next action from the request. Ask only when the requested action is unclear. - **If partially complete**: Inform the user and resume from the incomplete step. - **If not started**: Begin from the first step. @@ -51,7 +51,7 @@ If the memory bank exists, extract: Always tell the user what you found: -> "I found your project memory bank. [Summary: project name, version, what's been completed]. Let's continue from [next step]." +> "I found your project memory bank. [Summary: project name, what's been completed]. Let's continue from [next step]." --- @@ -107,7 +107,6 @@ Update after: | Environment Name | [ENVIRONMENT_NAME] | | Environment ID | [ENVIRONMENT_GUID — reference only, resolved by CLI] | | Remote git URL | [URL] | -| Version | v1.0.0 | | Created Date | [DATE] | | Status | [In Progress / Created / Local Dev Running / Deployed] | @@ -115,7 +114,6 @@ Update after: ### Design Preferences - Theme: [Dark/Light] -- Version Display: [Enabled/Disabled] ### Technical Preferences - Data Sources: [Dataverse, Azure DevOps, Teams, Excel, etc.] @@ -179,7 +177,7 @@ To continue working on this project: When reading the memory bank, extract: -1. **Project context**: Path, app name, environment, version. +1. **Project context**: Path, app name, environment. 2. **Completed work**: Check checkboxes to know what's done. 3. **User preferences**: Apply these without re-asking. 4. **Created resources**: Know what data sources/connectors exist. diff --git a/plugins/microsoft-managed-apps/shared/planning-policy.md b/plugins/microsoft-managed-apps/shared/planning-policy.md index 3ac08be..9e5bc10 100644 --- a/plugins/microsoft-managed-apps/shared/planning-policy.md +++ b/plugins/microsoft-managed-apps/shared/planning-policy.md @@ -41,11 +41,16 @@ Before exiting plan mode, ensure your plan covers: ## Plan Dump for Debugging -**After the plan is finalized and before calling `ExitPlanMode`, write a file `/app_generated_plan.md`** containing: +Write a file `/app_generated_plan.md` containing: 1. **User Request** — the original user prompt / app description that triggered planning. 2. **Generated Plan** — the full plan presented to the user for approval. +### When to write it + +- **Existing project** (`PROJECT_ROOT` already exists): write it after the plan is finalized and before calling `ExitPlanMode`. +- **New app creation**: `PROJECT_ROOT` does not exist yet, write it immediately **after** the app is scaffolded and `PROJECT_ROOT` is set, before implementing the app. It is then tracked in the app's Git repository. + ### Format ```markdown diff --git a/plugins/microsoft-managed-apps/shared/shared-instructions.md b/plugins/microsoft-managed-apps/shared/shared-instructions.md index c46f487..058b7bd 100644 --- a/plugins/microsoft-managed-apps/shared/shared-instructions.md +++ b/plugins/microsoft-managed-apps/shared/shared-instructions.md @@ -63,10 +63,9 @@ The memory bank persists context across sessions. Every skill reads it at start **📋 [development-standards.md](./development-standards.md)** -Standards for versioning, theme, build workflow, and TypeScript strict mode. +Standards for theme, build workflow, and TypeScript strict mode. **Key Points:** -- Always display the app version in the UI; increment on each deploy. - Default to dark theme (user can override). - Always `npm run build` before `ms app deploy` — never skip the build. - Always `git add -A`, commit, and push before `ms app deploy`. diff --git a/plugins/microsoft-managed-apps/skills/create-app/SKILL.md b/plugins/microsoft-managed-apps/skills/create-app/SKILL.md index eeb9426..0696e2f 100644 --- a/plugins/microsoft-managed-apps/skills/create-app/SKILL.md +++ b/plugins/microsoft-managed-apps/skills/create-app/SKILL.md @@ -19,15 +19,15 @@ This skill scaffolds a new Microsoft App end-to-end using `@microsoft/managed-ap ## Workflow -1. Memory Bank → 2. Prerequisites → 3. Gather Requirements → 4. Plan → 5. Auth → 6. Environment → 7. Scaffold → 8. Add Data Sources → 9. Implement App → 10. Local Dev → 11. Summary → 12. Memory Bank Update +1. Memory Bank → 2. Prerequisites → 3. Infer App Spec → 4. Plan → 5. Auth → 6. Environment → 7. Scaffold → 8. Add Data Sources → 9. Implement App → 10. Local Dev → 11. Summary → 12. Memory Bank Update -**Critical principle:** when this skill ends and the user opens the local URL, they must see a **functional app** — connectors wired, screens implemented per the approved plan — not a bare template. Adding data sources and implementing the UI happen **inside this skill**, before `ms app dev` is started. Do not defer them to "next steps." +**Critical principle:** when this skill ends and the user opens the local URL, they must see a **functional app** — connectors wired when required, screens implemented from the approved plan — not a bare template. Adding required data sources and implementing the UI happen **inside this skill**, before `ms app dev` is started. Do not defer them to "next steps." --- ### Step 1: Check Memory Bank -Check for `memory-bank.md` per [shared-instructions.md](${CLAUDE_PLUGIN_ROOT}/shared/shared-instructions.md). If found, ask the user whether they want to resume (e.g., re-run `ms app dev` against an existing scaffold) or start a new app. +Check for `memory-bank.md` per [shared-instructions.md](${CLAUDE_PLUGIN_ROOT}/shared/shared-instructions.md). If found, infer whether to resume or create a new app from the request: resume when it refers to the existing app or incomplete work; create a new sibling project when it clearly describes a different app. State the choice and continue. Ask only when the request genuinely fits both paths and choosing incorrectly could overwrite or modify existing work. ### Step 2: Validate Prerequisites @@ -77,27 +77,23 @@ if [ -n "$LATEST" ] && [ "$INSTALLED" != "$LATEST" ]; then fi ``` -Ask before running the upgrade. Don't auto-update without consent. +Do not interrupt app creation to offer an optional upgrade. Continue with the installed compatible version and mention the available upgrade in the final summary. Upgrade only when the user explicitly asks for it; never auto-update. -### Step 3: Gather Requirements +### Step 3: Infer App Spec -**Skip questions the user already answered in their initial prompt.** +**Default to action, not an interview. Ask only when progress is impossible without information that cannot be discovered or safely inferred.** If the user has not described what they want to build (i.e., `/create-app` was invoked with no arguments or a vague prompt), start with a single open-ended question: > "What would you like to build? Describe it in your own words — what it does, who uses it, and what problem it solves." -Wait for their answer. Use it to frame all follow-up questions. Do NOT present a multiple-choice list of app types before the user has described their idea. +Wait for their answer. Do NOT present a multiple-choice list of app types. Once the app idea is known, infer the rest: -Once you have their description: - -1. **Confirm the app name.** Use `--display-name` (free-form, can contain spaces). -2. **Ask about data.** Focus on what the app needs to do, not specific technologies: - - "What data does your app need to work with?" - - "Does it need to search existing information, manage its own data, or both?" - - Based on the answers, identify the connector(s) and the matching `/add-*` skill (or `/add-data-source` with an api-id) that will be invoked in Step 8. Capture **all** info those skills will need (connection IDs, table/list names, api-id, environment URL, etc.) — you will run them yourself, not hand them off. -3. **Ask about UI:** key screens, layout, interactions, theme preference. Capture enough detail to actually generate the components in Step 9. -4. Resolve all ambiguity now — easier than re-planning mid-scaffold. The user should approve the plan once and not be asked to approve sub-steps later. +1. **Generate the display name.** If the user already gave a name, use it verbatim. Otherwise derive a short title from the user's prompt (usually 2-5 title-cased words) and use it with `--display-name`. Either way, do not ask the user to name or confirm it. Derive the folder slug from this title. +2. **Plan the complete requested experience.** Include every capability the user clearly describes. Infer the screens, navigation, interactions, and visual styling needed to make those capabilities usable; use a single responsive screen only when it can support the full request cleanly. Do not ask separate questions about layout, theme, or architecture. Present these decisions in the plan for approval. +3. **Infer data needs from user intent.**. Add the appropriate connector whenever the requested experience clearly depends on user, organizational, shared, persistent, or external data, even if the user does not mention a connector. Use local sample data only when the experience is genuinely self-contained or the data intent is unclear. Ask one focused question only when choosing incorrectly would materially change the app. +4. **Discover before asking.** When a connector is needed, infer its api-id and mode from the connector decision guide, and let the CLI discover or create connections where supported. Ask one focused question only if a required tenant-specific identifier cannot be discovered (for example, which of several matching SharePoint lists to use). +5. **Consolidate assumptions into the plan.** Include the generated name, requested capabilities, inferred UI, and any connector choice in one complete plan. Do not ask separate questions to confirm each assumption. ### Step 4: Plan @@ -107,8 +103,8 @@ Once you have their description: - **Each data source to be added** (which `/add-*` skill, api-id, table/list/connection identifiers). These are invoked by Step 8 of this skill — list them as concrete steps, not as "next steps." - **App architecture**: components, pages, routing, state management — enough detail that Step 9 can generate the code without re-asking. - Build/verify steps and the final `ms app dev` hand-off. -3. Present the plan for approval, including `allowedPrompts` from [prerequisites-reference.md](./references/prerequisites-reference.md). Be explicit: _"On approval, I'll scaffold, add the connectors, implement the UI, build, and start local dev. You won't be asked to confirm again until everything is running."_ -4. Exit plan mode with `ExitPlanMode` when approved. +3. Present the complete inferred plan. Include `allowedPrompts` from [prerequisites-reference.md](./references/prerequisites-reference.md) when the host requires them. +4. Once the plan is approved, implement it. Additional questions are allowed only when a required value cannot be inferred or discovered, or when mandated by the safety guardrails (for example, global installation or account switching). ### Step 5: Auth @@ -135,7 +131,15 @@ If environment routing fails, surface the actual error to the user rather than a ### Step 7: Scaffold -The CLI creates a new folder for the project. Derive a folder name from the display name (lowercase, hyphens, no spaces — e.g. "Sample One" → `sample-one`). Run the command from the **current working directory**; the CLI will create the subfolder automatically. +**If the user explicitly provided a folder name, use it verbatim** — do not generate one, and skip the inference below. Create it as a child of the current directory, unless the current directory is already named that (then set `FOLDER_NAME="."`). If they gave a full path, use that path as-is. Only fall back to a numbered variant if the target already exists, and say so. + +Otherwise, derive a folder slug from the display name (lowercase, hyphens, no spaces — e.g. "Sample One" → `sample-one`), then inspect the **current working directory**, including hidden entries, and pick the target: + +- **Directory is empty:** set `FOLDER_NAME="."` and scaffold directly into it. Do not ask for a path or app name. +- **Current directory is a Microsoft App root** (it contains `ms.config.json`): never scaffold inside it — that would nest an app and a Git repository inside another one. Create the new app as a **sibling**, so `FOLDER_NAME` is the slug under the parent directory (e.g. `../sample-one`). +- **Any other non-empty directory:** use the slug as a child folder. + +In both non-empty cases, if the chosen path already exists, select the first available numbered variant (`sample-one-2`, `sample-one-3`, etc.); never overwrite an existing directory. State the chosen location and continue immediately without asking for confirmation, e.g. _"Found current folder is not empty. I'll create the app in: ``."_ — or, for the sibling case, _"This folder is an existing Microsoft App, so I'll create the new app alongside it in: ``."_ ```bash $BIN app create "$FOLDER_NAME" \ @@ -144,13 +148,15 @@ $BIN app create "$FOLDER_NAME" \ # Append --environment-id "$ENV_ID" ONLY if the user explicitly provided an environment ID (see Step 6). ``` -After the command succeeds, `cd` into the new folder and set `PROJECT_ROOT`: +After the command succeeds, enter the target directory unless it is `.`, then set `PROJECT_ROOT`: ```bash -cd "$FOLDER_NAME" +[ "$FOLDER_NAME" = "." ] || cd "$FOLDER_NAME" PROJECT_ROOT="$(pwd)" ``` +Now that `PROJECT_ROOT` exists, write the approved plan to `$PROJECT_ROOT/app_generated_plan.md` per [planning-policy.md](${CLAUDE_PLUGIN_ROOT}/shared/planning-policy.md) — before any implementation, so it is committed with the rest of the generated app. + Capture from the output: the app GUID, the environment ID/name resolved by the CLI, and the remote git URL. (The environment ID appears in the App Player URL and is needed for that link — it's an internal detail, not something to surface to the user.) #### First-run Git Credential Manager recovery @@ -191,7 +197,7 @@ Run them sequentially. After each one: - Other `/add-*` skills have similar guidance - Capture the connection ID + service path so Step 9 can import them. -**Forward all captured context to each sub-skill so its own gather-info prompts are suppressed.** The per-service skills (`/add-dataverse`, `/add-sharepoint`, etc.) and `/add-data-source` each have their own prompt sequences (pick connection, pick table/list/site, choose api-id, etc.). The plan you got the user to approve in Step 4 already contains those answers, so pass them through as `$ARGUMENTS` (or whatever invocation surface is available) when dispatching: api-id, connection ID or name, table/list/site identifiers, environment URL, and the project root. If a sub-skill still needs an input you didn't capture, that's a Step 4 gap — go back and ask the user once, then update the plan, rather than letting the sub-skill ask interactively. +**Forward all captured context to each sub-skill so its own gather-info prompts are suppressed.** The per-service skills (`/add-dataverse`, `/add-sharepoint`, etc.) and `/add-connector` each have their own prompt sequences (pick connection, pick table/list/site, choose api-id, etc.). The approved plan and discovery results should contain those answers, so pass them through as `$ARGUMENTS` (or whatever invocation surface is available) when dispatching: api-id, connection ID or name, table/list/site identifiers, environment URL, and the project root. If a sub-skill still needs a required input that cannot be discovered or safely inferred, ask the user one focused question and record the answer as an amendment to the approved plan rather than letting multiple sub-skills ask interactively. The intent of this step is no per-connector approval prompts: the approved plan from Step 4 covers them. If a sub-skill fails (auth, missing connection, wrong api-id), surface the error verbatim and stop; do not silently proceed with a half-wired app. @@ -203,7 +209,7 @@ Generate the code that delivers the experience described in the approved plan: - Components, pages, routing, state management. - Wire each component to the typed services produced in Step 8 (no raw `fetch` / `axios` / Graph calls — see [shared-instructions.md](${CLAUDE_PLUGIN_ROOT}/shared/shared-instructions.md)). -- Apply the theme/UI preferences captured in Step 3. +- Apply the inferred theme and UI decisions documented in the approved plan. - Replace template placeholder content; the user must see *their* app at the local URL, not "Hello World." When the implementation is complete, the next step's `npm run build` is the gate that proves everything compiles end-to-end. @@ -236,7 +242,7 @@ The dev server runs in the foreground. Either: Provide: -- **App**: display name, app GUID, version `v1.0.0`. +- **App**: display name, app GUID. - **Project path**: `$PROJECT_ROOT`. - **Git remote URL** (label it "Git Remote", not just "Remote" — users confuse "Remote" with a browser-openable link). - **Connectors wired up**: list each one added in Step 8 + which screens use it. @@ -301,7 +307,7 @@ ms app dev ``` Sample One is running locally. -App: Sample One v1.0.0 +App: Sample One App GUID: 7ea6... Environment: Default- (auto-routed Developer environment) Cluster: prod diff --git a/plugins/microsoft-managed-apps/skills/create-app/references/prerequisites-reference.md b/plugins/microsoft-managed-apps/skills/create-app/references/prerequisites-reference.md index 5b3643b..08e9034 100644 --- a/plugins/microsoft-managed-apps/skills/create-app/references/prerequisites-reference.md +++ b/plugins/microsoft-managed-apps/skills/create-app/references/prerequisites-reference.md @@ -40,7 +40,7 @@ PowerShell equivalent: $Latest = (npm view @microsoft/managed-apps-cli@latest version 2>$null).Trim() ``` -If the installed version differs from `$Latest`, ask the user before upgrading. The `@latest` tag updates regularly. +If the installed version differs from `$Latest`, continue app creation with the compatible installed version and mention the available upgrade in the final summary. Upgrade only when the user explicitly asks; never auto-update. ### Override patterns (only with explicit user direction) diff --git a/plugins/microsoft-managed-apps/skills/create-app/references/troubleshooting.md b/plugins/microsoft-managed-apps/skills/create-app/references/troubleshooting.md index dddc27a..0c2f385 100644 --- a/plugins/microsoft-managed-apps/skills/create-app/references/troubleshooting.md +++ b/plugins/microsoft-managed-apps/skills/create-app/references/troubleshooting.md @@ -38,7 +38,7 @@ Match `Could not commit and push the initial scaffold` together with `Authentica | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `defau.lt.environment.api.powerplatform.com: no such host` (or similar DNS error) | A malformed `--environment-id` value was passed (this only happens when the user supplied one). | Surface the error. Drop the explicit `--environment-id` and let `ms app create` auto-route, or have the user supply a valid environment ID. | | `Could not provision a Developer environment for your tenant (status 403)` | Routing service rejected the account. Tenant Governance may block Developer envs. | Surface the error to the user — provisioning is blocked at the tenant level and the plugin cannot work around it. The user (or their tenant admin) needs to resolve the governance/access issue. | -| `Directory not empty; pass --force` | Current project folder has prior files. | Run `/create-app` from an empty folder, or confirm using `--force` only when you intend to overwrite. | +| `Directory not empty; pass --force` | The selected target folder has prior files. | Pick another target per [Step 7: Scaffold](../SKILL.md) (child folder, or a sibling when inside an existing app) and retry. Use `--force` only when the user explicitly asks for it. | | Repo init fails (`fatal: not in a git repository`) | Git is missing or `git config user.email` / `user.name` are unset. | Install Git; run `git config --global user.email "@microsoft.com"` and `... user.name ""`. | ## Common Build / Dev Failures diff --git a/plugins/microsoft-managed-apps/skills/deploy/SKILL.md b/plugins/microsoft-managed-apps/skills/deploy/SKILL.md index 8a3c5b9..3924783 100644 --- a/plugins/microsoft-managed-apps/skills/deploy/SKILL.md +++ b/plugins/microsoft-managed-apps/skills/deploy/SKILL.md @@ -22,7 +22,7 @@ Before any deploy, sync source control first: stage all changes, create a commit ### Step 1: Check Memory Bank -Read `memory-bank.md` for app slug, GUID, environment, and version. +Read `memory-bank.md` for app slug, GUID, and environment. ### Step 2: Verify Project + Env @@ -125,7 +125,6 @@ $BIN app play --mode preview # opens the latest code on main (no deploy needed If `memory-bank.md` exists: -- Increment version (e.g., `v1.0.0` → `v1.1.0`) per [development-standards.md](${CLAUDE_PLUGIN_ROOT}/shared/development-standards.md). Bump the version display in the app UI too. - Update "Last deployed" timestamp. - Record the deploy path used (standard / traced). - Capture the commit SHA at deploy time.