[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ADJDBCREKRN8605HFCN0K4":3,"skill-same:01M6ADJDBCREKRN8605HFCN0K4":111},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":62,"ownerHtmlUrl":63,"ownerBlogUrl":64,"ownerDescription":65,"updatedAt":66,"install":67,"resources":80},"01M6ADJDBCREKRN8605HFCN0K4","flowstudio-power-automate-build",null,"Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio MCP server. Your agent constructs flow definitions, wires connections, deploys, and tests — all via MCP without opening the portal. Load this skill when asked to: create a flow, build a new flow, deploy a flow definition, scaffold a Power Automate workflow, construct a flow JSON, update an existing flow's actions, patch a flow definition, add actions to a flow, wire up connections, or generate a workflow definition from scratch. Requires a FlowStudio MCP subscription — see https:\u002F\u002Fmcp.flowstudio.app","github\u002Fawesome-copilot","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6AD3PBDYPK7NVFJNJ66Y8RS",41133,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"power automate build","build","power","flowstudio power automate build","automate","new","MCP","when","definition","flows","app","constructs","patch","up","actions","cloud","server","https","update","generate","create","scaffold","deploy","workflow","mcp server","2026-11-10 10:12:30",false,"---\nname: flowstudio-power-automate-build\ndescription: >-\n  Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio\n  MCP server. Your agent constructs flow definitions, wires connections, deploys,\n  and tests — all via MCP without opening the portal.\n  Load this skill when asked to: create a flow, build a new flow,\n  deploy a flow definition, scaffold a Power Automate workflow, construct a flow\n  JSON, update an existing flow's actions, patch a flow definition, add actions\n  to a flow, wire up connections, or generate a workflow definition from scratch.\n  Requires a FlowStudio MCP subscription — see https:\u002F\u002Fmcp.flowstudio.app\n---\n\n# Build & Deploy Power Automate Flows with FlowStudio MCP\n\nStep-by-step guide for constructing and deploying Power Automate cloud flows\nprogrammatically through the FlowStudio MCP server.\n\n**Prerequisite**: A FlowStudio MCP server must be reachable with a valid JWT.\nSee the `flowstudio-power-automate-mcp` skill for connection setup.\nSubscribe at https:\u002F\u002Fmcp.flowstudio.app\n\nWorkflow:\n1. Load current build tools.\n2. Check for an existing flow.\n3. Resolve connection references.\n4. Build the definition.\n5. Deploy.\n6. Verify.\n7. Test.\n\n---\n\n## Source of Truth\n\n> **Always call `list_skills` \u002F `tool_search` first** to confirm available tool\n> names and parameter schemas. Tool names and parameters may change between\n> server versions.\n> This skill covers response shapes, behavioral notes, and build patterns —\n> things tool schemas cannot tell you. If this document disagrees with\n> `tool_search` or a real API response, the API wins.\n\n---\n\n## Python Helper\n\n```python\nimport json, urllib.request\n\nMCP_URL   = \"https:\u002F\u002Fmcp.flowstudio.app\u002Fmcp\"\nMCP_TOKEN = \"\u003CYOUR_JWT_TOKEN>\"\n\ndef mcp(tool, **kwargs):\n    payload = json.dumps({\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools\u002Fcall\",\n                          \"params\": {\"name\": tool, \"arguments\": kwargs}}).encode()\n    req = urllib.request.Request(MCP_URL, data=payload,\n        headers={\"x-api-key\": MCP_TOKEN, \"Content-Type\": \"application\u002Fjson\",\n                 \"User-Agent\": \"FlowStudio-MCP\u002F1.0\"})\n    try:\n        resp = urllib.request.urlopen(req, timeout=120)\n    except urllib.error.HTTPError as e:\n        body = e.read().decode(\"utf-8\", errors=\"replace\")\n        raise RuntimeError(f\"MCP HTTP {e.code}: {body[:200]}\") from e\n    raw = json.loads(resp.read())\n    if \"error\" in raw:\n        raise RuntimeError(f\"MCP error: {json.dumps(raw['error'])}\")\n    return json.loads(raw[\"result\"][\"content\"][0][\"text\"])\n\nENV = \"\u003Cenvironment-id>\"  # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\n---\n\n## 0. Load the Current Build Tools\n\nFor a brand-new flow, load the server's `create-flow` bundle. For editing an\nexisting flow, load `build-flow`. This keeps the agent aligned with the MCP\nserver's current schema before constructing JSON.\n\n```python\nschemas = mcp(\"tool_search\", query=\"skill:create-flow\")\n# Includes list_live_environments, list_live_connections,\n# describe_live_connector, get_live_dynamic_options, update_live_flow.\n```\n\nIf you need a tool outside the bundle, load it explicitly:\n\n```python\nmcp(\"tool_search\", query=\"select:get_live_dynamic_properties\")\n```\n\n---\n\n## 1. Safety Check: Does the Flow Already Exist?\n\nAlways look before you build to avoid duplicates:\n\n```python\nresults = mcp(\"list_live_flows\",\n    environmentName=ENV,\n    mode=\"owner\",\n    search=\"My New Flow\",\n    top=20)\n\n# list_live_flows returns { \"flows\": [...], \"mode\": \"...\", ... }\nmatches = [f for f in results[\"flows\"]\n           if \"My New Flow\".lower() in f[\"displayName\"].lower()]\n\nif len(matches) > 0:\n    # Flow exists — modify rather than create\n    FLOW_ID = matches[0][\"id\"]   # plain UUID from list_live_flows\n    print(f\"Existing flow: {FLOW_ID}\")\n    defn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\nelse:\n    print(\"Flow not found — building from scratch\")\n    FLOW_ID = None\n```\n\nFor very large environments, `list_live_flows` may return a continuation URL.\nPass it back as `continuationUrl` with the same `mode` to retrieve the next\nbatch. Use `mode=\"admin\"` only when the user needs all environment flows and\nthe MCP identity has admin rights.\n\n---\n\n## 2. Obtain Connection References\n\nEvery connector action needs a `connectionName` that points to a key in the\nflow's `connectionReferences` map. That key links to an authenticated connection\nin the environment.\n\n> **MANDATORY**: You MUST call `list_live_connections` first — do NOT ask the\n> user for connection names or GUIDs. The API returns the exact values you need.\n> Only prompt the user if the API confirms that required connections are missing.\n\n### 2a — Find active connections\n\n```python\nconns = mcp(\"list_live_connections\", environmentName=ENV)\nactive = [c for c in conns[\"connections\"]\n          if c[\"statuses\"][0][\"status\"] == \"Connected\"]\nconn_map = {c[\"connectorName\"]: c[\"id\"] for c in active}\n```\n\nFor a known connector, pass `search` to reduce output and get paste-ready\n`connectionReferenceTemplate` and `hostTemplate` values:\n\n```python\nsp_conns = mcp(\"list_live_connections\",\n    environmentName=ENV,\n    search=\"shared_sharepointonline\")\n```\n\n### 2b — Determine which connectors the flow needs\n\nCommon connector API names: SharePoint `shared_sharepointonline`, Outlook\n`shared_office365`, Teams `shared_teams`, Approvals `shared_approvals`,\nOneDrive `shared_onedriveforbusiness`, Excel `shared_excelonlinebusiness`,\nDataverse `shared_commondataserviceforapps`, Forms `shared_microsoftforms`.\n\nFlows that need no connectors, such as Recurrence + Compose + HTTP only, can\nomit `connectionReferences`.\n\n### 2c — If connections are missing, guide the user\n\n```python\nconnectors_needed = [\"shared_sharepointonline\", \"shared_office365\"]  # adjust per flow\nmissing = [c for c in connectors_needed if c not in conn_map]\nif missing:\n    # STOP: connections require browser OAuth consent.\n    # Ask the user to create the missing connector connections in the\n    # selected environment, then re-run list_live_connections.\n    raise Exception(f\"Missing active connections: {missing}\")\n```\n\n### 2d — Build the connectionReferences block\n\n```python\nconnection_references = {}\nhost_templates = {}\nfor connector in connectors_needed:\n    c = next(c for c in active if c[\"connectorName\"] == connector)\n    connection_references[connector] = c.get(\"connectionReferenceTemplate\") or {\n        \"connectionName\": c[\"id\"],   # the connection id from list_live_connections\n        \"source\": \"Invoker\",\n        \"id\": f\"\u002Fproviders\u002FMicrosoft.PowerApps\u002Fapis\u002F{connector}\"\n    }\n    host_templates[connector] = c.get(\"hostTemplate\") or {\n        \"connectionName\": connector\n    }\n```\n\nIn Step 3 action JSON, `inputs.host.connectionName` must be the map key such as\n`shared_teams`, not the GUID. The GUID belongs only inside the\n`connectionReferences[connector].connectionName` value. If an existing flow uses\nthe same connectors, you may also copy its `properties.connectionReferences`\nfrom `get_live_flow`.\n\n---\n\n## 3. Build the Flow Definition\n\nConstruct the definition object. See [flow-schema.md](references\u002Fflow-schema.md)\nfor the full schema and these action pattern references for copy-paste templates:\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n\n```python\ndefinition = {\n    \"$schema\": \"https:\u002F\u002Fschema.management.azure.com\u002Fproviders\u002FMicrosoft.Logic\u002Fschemas\u002F2016-06-01\u002Fworkflowdefinition.json#\",\n    \"contentVersion\": \"1.0.0.0\",\n    \"triggers\": { ... },   # see trigger-types.md \u002F build-patterns.md\n    \"actions\": { ... }     # see ACTION-PATTERNS-*.md \u002F build-patterns.md\n}\n```\n\n> See [build-patterns.md](references\u002Fbuild-patterns.md) for complete, ready-to-use\n> flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.\n\n### Discover connector operations before guessing JSON\n\nFor connector-backed triggers\u002Factions, prefer the live connector describer over\nhand-written shapes. It can return authored hints, canonical examples, variant\nkeys, inputs\u002Foutputs, and dynamic metadata pointers.\n\n```python\n# Search across connectors when you know the user's intent but not the API.\nmatches = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    search=\"send email\",\n    top=5)\n\n# Describe a specific operation before copying an exampleDefinition.\nop = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_office365\",\n    operationId=\"SendEmailV2\")\nprint(op.get(\"hint\"))\n```\n\nWhen an operation has multiple authored variants, request the variant the flow\nneeds:\n\n```python\nteams_chat = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_teams\",\n    operationId=\"PostMessageToConversation\",\n    variant=\"flowbot_chat\")\n```\n\nWhen the operation description says a parameter has dynamic options or dynamic\nproperties, call the indicated next tool:\n\n```python\nsp_op = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    operationId=\"GetItems\")\n\nsites = mcp(\"get_live_dynamic_options\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"dataset\",\n    dynamicMetadata=sp_op[\"dynamicParameters\"][\"dataset\"])\n\nfields = mcp(\"get_live_dynamic_properties\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"item\",\n    parameters={\"dataset\": \"\u003Csite-url>\", \"table\": \"\u003Clist-id>\"},\n    dynamicMetadata=sp_op[\"dynamicProperties\"][\"item\"])\n```\n\nUse dynamic options for dropdown IDs such as SharePoint sites\u002Flists and Teams\nteams\u002Fchannels. Use dynamic properties for schema\u002Ffield shapes such as\nSharePoint list item columns.\n\n---\n\n## 4. Deploy (Create or Update)\n\n`update_live_flow` handles both creation and updates in a single tool.\n\n### Create a new flow (no existing flow)\n\nOmit `flowName` — the server generates a new GUID and creates via PUT:\n\n```python\ndefinition[\"description\"] = \"Weekly SharePoint → Teams notification flow, built by agent\"\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    # flowName omitted → creates a new flow\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Create failed:\", result[\"error\"])\nelse:\n    # Capture the new flow ID for subsequent steps\n    FLOW_ID = result[\"created\"]\n    print(f\"✅ Flow created: {FLOW_ID}\")\n```\n\n### Update an existing flow\n\nProvide `flowName` to PATCH:\n\n```python\ndefinition[\"description\"] = (\n    \"Updated by agent on \" + __import__('datetime').datetime.utcnow().isoformat()\n)\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    flowName=FLOW_ID,\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"My Updated Flow\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Update failed:\", result[\"error\"])\nelse:\n    print(\"Update succeeded:\", result)\n```\n\n> ⚠️ `update_live_flow` always returns an `error` key.\n> `null` (Python `None`) means success — do not treat the presence of the key as failure.\n>\n> ⚠️ Flow description lives at `definition[\"description\"]`. The current server\n> appends `#flowstudio-mcp` for usage tracking. Do not pass a top-level\n> `description` argument unless `tool_search` shows one in the active schema.\n\n### Common deployment errors\n\n| Error message (contains) | Cause | Fix |\n|---|---|---|\n| `missing from connectionReferences` | An action's `host.connectionName` references a key that doesn't exist in the `connectionReferences` map | Ensure `host.connectionName` uses the **key** from `connectionReferences` (e.g. `shared_teams`), not the raw GUID |\n| `ConnectionAuthorizationFailed` \u002F 403 | The connection GUID belongs to another user or is not authorized | Re-run Step 2a and use a connection owned by the current `x-api-key` user |\n| `InvalidTemplate` \u002F `InvalidDefinition` | Syntax error in the definition JSON | Check `runAfter` chains, expression syntax, and action type spelling |\n| `ConnectionNotConfigured` | A connector action exists but the connection GUID is invalid or expired | Re-check `list_live_connections` for a fresh GUID |\n\n---\n\n## 5. Verify the Deployment\n\n```python\ncheck = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\n\n# Confirm state\nprint(\"State:\", check[\"properties\"][\"state\"])  # Should be \"Started\"\n# If state is \"Stopped\", use set_live_flow_state — NOT update_live_flow\n# mcp(\"set_live_flow_state\", environmentName=ENV, flowName=FLOW_ID, state=\"Started\")\n\n# Confirm the action we added is there\nacts = check[\"properties\"][\"definition\"][\"actions\"]\nprint(\"Actions:\", list(acts.keys()))\n```\n\n---\n\n## 6. Test the Flow\n\n> **MANDATORY**: Before triggering any test run, **ask the user for confirmation**.\n> Running a flow has real side effects — it may send emails, post Teams messages,\n> write to SharePoint, start approvals, or call external APIs. Explain what the\n> flow will do and wait for explicit approval before calling `trigger_live_flow`\n> or `resubmit_live_flow_run`.\n\n### Updated flows (have prior runs) — ANY trigger type\n\n> **Use `resubmit_live_flow_run` first.** It works for EVERY trigger type —\n> Recurrence, SharePoint, connector webhooks, Button, and HTTP. It replays\n> the original trigger payload. Do NOT ask the user to manually trigger the\n> flow or wait for the next scheduled run.\n\n```python\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs:\n    # Works for Recurrence, SharePoint, connector triggers — not just HTTP\n    result = mcp(\"resubmit_live_flow_run\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    print(result)   # {\"resubmitted\": true, \"triggerName\": \"...\"}\n```\n\n### HTTP, Button, and PowerApps flows — custom test payload\n\nOnly use `trigger_live_flow` when you need to send a **different** payload\nthan the original run. For verifying a fix, `resubmit_live_flow_run` is\nbetter because it uses the exact data that caused the failure.\n\n```python\ndefn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\ntriggers = defn[\"properties\"][\"definition\"][\"triggers\"]\nmanual = next(iter(triggers.values()))\nprint(\"Expected body:\", manual.get(\"inputs\", {}).get(\"schema\"))\n\nresult = mcp(\"trigger_live_flow\",\n    environmentName=ENV, flowName=FLOW_ID,\n    body={\"name\": \"Test\", \"value\": 1})\nprint(f\"Status: {result['responseStatus']}, via: {result['invocation']}\")\nprint(result.get(\"warning\"))   # set when a required input was missing: the run still ran, with null\n```\n\n### Brand-new non-HTTP flows\n\nA brand-new **Recurrence** flow needs no workaround: deploy it, then run it\nimmediately with `trigger_live_flow` and no `body` — same as the portal's\n\"Run flow\" button. A body is refused; scheduled triggers take no inputs.\n\nA brand-new **connector-triggered** flow (SharePoint, webhooks) has no prior\nruns and cannot fire without a real source event. Deploy with a temporary\nHTTP trigger, test the actions, then swap to the production trigger:\n\n```python\nproduction_trigger = definition[\"triggers\"]\ndefinition[\"triggers\"] = {\n    \"manual\": {\"type\": \"Request\", \"kind\": \"Http\", \"inputs\": {\"schema\": {}}}\n}\nresult = mcp(\"update_live_flow\", environmentName=ENV,\n    flowName=FLOW_ID,       # omit if creating new\n    definition=definition, connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\")\nFLOW_ID = FLOW_ID or result[\"flowName\"]\n\nmcp(\"trigger_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    body={\"sample\": \"payload\"})\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs[0][\"status\"] == \"Failed\":\n    err = mcp(\"get_live_flow_run_error\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    raise Exception(err[\"failedActions\"][-1])\n\ndefinition[\"triggers\"] = production_trigger\nmcp(\"update_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    definition=definition, connectionReferences=connection_references)\n```\n\nThe trigger is only the entry point; testing through HTTP still exercises the\nsame actions. If actions use `triggerBody()` or `triggerOutputs()`, pass a\nrepresentative `body` shaped like the production trigger payload.\n\n---\n\n## Gotchas\n\n| Mistake | Consequence | Prevention |\n|---|---|---|\n| Missing `connectionReferences` in deploy | 400 \"Supply connectionReferences\" | Always call `list_live_connections` first |\n| `\"operationOptions\"` missing on Foreach | Parallel execution, race conditions on writes | Always add `\"Sequential\"` |\n| `union(old_data, new_data)` | Old values override new (first-wins) | Use `union(new_data, old_data)` |\n| `split()` on potentially-null string | `InvalidTemplate` crash | Wrap with `coalesce(field, '')` |\n| Checking `result[\"error\"]` exists | Always present; true error is `!= null` | Use `result.get(\"error\") is not None` |\n| Flow deployed but state is \"Stopped\" | Flow won't run on schedule | Call `set_live_flow_state` with `state: \"Started\"` — do **not** use `update_live_flow` for state changes |\n| Teams \"Chat with Flow bot\" recipient as object | 400 `GraphUserDetailNotFound` | Use plain string with trailing semicolon (see below) |\n| Copilot\u002FSkills flow not in a solution | Copilot Studio may not discover it as an agent tool | After deploy, call `add_live_flow_to_solution` with the target `solutionId` |\n| Button\u002FSkills trigger used for MCP testing | Runs even when a required input is missing (null) | Pass inputs in `trigger_live_flow` `body`; on `warning`, cancel and retry with the full body |\n| Connector action missing `metadata.operationMetadataId` | Designer\u002Frun-only UI can behave inconsistently | Preserve existing IDs; add stable GUIDs for new connector actions |\n| Placeholder Excel `scriptId` | Dynamic validation fails at save time | Resolve the real Office Script ID before deploying |\n| SharePoint `PatchItem` omits required fields | Save can fail even if the field is not changing | Echo unchanged required fields such as `item\u002FTitle` |\n| Copilot Studio connector calls a draft agent | Connector invocation can fail or hit stale behavior | Publish the agent before testing\u002Fresubmitting the flow |\n\n### Teams `PostMessageToConversation` — Recipient Formats\n\nThe `body\u002Frecipient` parameter format depends on the `location` value:\n\n| Location | `body\u002Frecipient` format | Example |\n|---|---|---|\n| **Chat with Flow bot** | Plain email string with **trailing semicolon** | `\"user@contoso.com;\"` |\n| **Channel** | Object with `groupId` and `channelId` | `{\"groupId\": \"...\", \"channelId\": \"...\"}` |\n\n> **Common mistake**: passing `{\"to\": \"user@contoso.com\"}` for \"Chat with Flow bot\"\n> returns a 400 `GraphUserDetailNotFound` error. The API expects a plain string.\n\n---\n\n## Reference Files\n\n- [flow-schema.md](references\u002Fflow-schema.md) — Full flow definition JSON schema\n- [trigger-types.md](references\u002Ftrigger-types.md) — Trigger type templates\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n- [build-patterns.md](references\u002Fbuild-patterns.md) — Complete flow definition templates (Recurrence+SP+Teams, HTTP trigger)\n\n## Related Skills\n\n- `flowstudio-power-automate-mcp` — Core connection setup and tool reference\n- `flowstudio-power-automate-debug` — Debug failing flows after deployment\n","# Build & Deploy Power Automate Flows with FlowStudio MCP\n\nStep-by-step guide for constructing and deploying Power Automate cloud flows\nprogrammatically through the FlowStudio MCP server.\n\n**Prerequisite**: A FlowStudio MCP server must be reachable with a valid JWT.\nSee the `flowstudio-power-automate-mcp` skill for connection setup.\nSubscribe at https:\u002F\u002Fmcp.flowstudio.app\n\nWorkflow:\n1. Load current build tools.\n2. Check for an existing flow.\n3. Resolve connection references.\n4. Build the definition.\n5. Deploy.\n6. Verify.\n7. Test.\n\n---\n\n## Source of Truth\n\n> **Always call `list_skills` \u002F `tool_search` first** to confirm available tool\n> names and parameter schemas. Tool names and parameters may change between\n> server versions.\n> This skill covers response shapes, behavioral notes, and build patterns —\n> things tool schemas cannot tell you. If this document disagrees with\n> `tool_search` or a real API response, the API wins.\n\n---\n\n## Python Helper\n\n```python\nimport json, urllib.request\n\nMCP_URL   = \"https:\u002F\u002Fmcp.flowstudio.app\u002Fmcp\"\nMCP_TOKEN = \"\u003CYOUR_JWT_TOKEN>\"\n\ndef mcp(tool, **kwargs):\n    payload = json.dumps({\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools\u002Fcall\",\n                          \"params\": {\"name\": tool, \"arguments\": kwargs}}).encode()\n    req = urllib.request.Request(MCP_URL, data=payload,\n        headers={\"x-api-key\": MCP_TOKEN, \"Content-Type\": \"application\u002Fjson\",\n                 \"User-Agent\": \"FlowStudio-MCP\u002F1.0\"})\n    try:\n        resp = urllib.request.urlopen(req, timeout=120)\n    except urllib.error.HTTPError as e:\n        body = e.read().decode(\"utf-8\", errors=\"replace\")\n        raise RuntimeError(f\"MCP HTTP {e.code}: {body[:200]}\") from e\n    raw = json.loads(resp.read())\n    if \"error\" in raw:\n        raise RuntimeError(f\"MCP error: {json.dumps(raw['error'])}\")\n    return json.loads(raw[\"result\"][\"content\"][0][\"text\"])\n\nENV = \"\u003Cenvironment-id>\"  # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\n---\n\n## 0. Load the Current Build Tools\n\nFor a brand-new flow, load the server's `create-flow` bundle. For editing an\nexisting flow, load `build-flow`. This keeps the agent aligned with the MCP\nserver's current schema before constructing JSON.\n\n```python\nschemas = mcp(\"tool_search\", query=\"skill:create-flow\")\n# Includes list_live_environments, list_live_connections,\n# describe_live_connector, get_live_dynamic_options, update_live_flow.\n```\n\nIf you need a tool outside the bundle, load it explicitly:\n\n```python\nmcp(\"tool_search\", query=\"select:get_live_dynamic_properties\")\n```\n\n---\n\n## 1. Safety Check: Does the Flow Already Exist?\n\nAlways look before you build to avoid duplicates:\n\n```python\nresults = mcp(\"list_live_flows\",\n    environmentName=ENV,\n    mode=\"owner\",\n    search=\"My New Flow\",\n    top=20)\n\n# list_live_flows returns { \"flows\": [...], \"mode\": \"...\", ... }\nmatches = [f for f in results[\"flows\"]\n           if \"My New Flow\".lower() in f[\"displayName\"].lower()]\n\nif len(matches) > 0:\n    # Flow exists — modify rather than create\n    FLOW_ID = matches[0][\"id\"]   # plain UUID from list_live_flows\n    print(f\"Existing flow: {FLOW_ID}\")\n    defn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\nelse:\n    print(\"Flow not found — building from scratch\")\n    FLOW_ID = None\n```\n\nFor very large environments, `list_live_flows` may return a continuation URL.\nPass it back as `continuationUrl` with the same `mode` to retrieve the next\nbatch. Use `mode=\"admin\"` only when the user needs all environment flows and\nthe MCP identity has admin rights.\n\n---\n\n## 2. Obtain Connection References\n\nEvery connector action needs a `connectionName` that points to a key in the\nflow's `connectionReferences` map. That key links to an authenticated connection\nin the environment.\n\n> **MANDATORY**: You MUST call `list_live_connections` first — do NOT ask the\n> user for connection names or GUIDs. The API returns the exact values you need.\n> Only prompt the user if the API confirms that required connections are missing.\n\n### 2a — Find active connections\n\n```python\nconns = mcp(\"list_live_connections\", environmentName=ENV)\nactive = [c for c in conns[\"connections\"]\n          if c[\"statuses\"][0][\"status\"] == \"Connected\"]\nconn_map = {c[\"connectorName\"]: c[\"id\"] for c in active}\n```\n\nFor a known connector, pass `search` to reduce output and get paste-ready\n`connectionReferenceTemplate` and `hostTemplate` values:\n\n```python\nsp_conns = mcp(\"list_live_connections\",\n    environmentName=ENV,\n    search=\"shared_sharepointonline\")\n```\n\n### 2b — Determine which connectors the flow needs\n\nCommon connector API names: SharePoint `shared_sharepointonline`, Outlook\n`shared_office365`, Teams `shared_teams`, Approvals `shared_approvals`,\nOneDrive `shared_onedriveforbusiness`, Excel `shared_excelonlinebusiness`,\nDataverse `shared_commondataserviceforapps`, Forms `shared_microsoftforms`.\n\nFlows that need no connectors, such as Recurrence + Compose + HTTP only, can\nomit `connectionReferences`.\n\n### 2c — If connections are missing, guide the user\n\n```python\nconnectors_needed = [\"shared_sharepointonline\", \"shared_office365\"]  # adjust per flow\nmissing = [c for c in connectors_needed if c not in conn_map]\nif missing:\n    # STOP: connections require browser OAuth consent.\n    # Ask the user to create the missing connector connections in the\n    # selected environment, then re-run list_live_connections.\n    raise Exception(f\"Missing active connections: {missing}\")\n```\n\n### 2d — Build the connectionReferences block\n\n```python\nconnection_references = {}\nhost_templates = {}\nfor connector in connectors_needed:\n    c = next(c for c in active if c[\"connectorName\"] == connector)\n    connection_references[connector] = c.get(\"connectionReferenceTemplate\") or {\n        \"connectionName\": c[\"id\"],   # the connection id from list_live_connections\n        \"source\": \"Invoker\",\n        \"id\": f\"\u002Fproviders\u002FMicrosoft.PowerApps\u002Fapis\u002F{connector}\"\n    }\n    host_templates[connector] = c.get(\"hostTemplate\") or {\n        \"connectionName\": connector\n    }\n```\n\nIn Step 3 action JSON, `inputs.host.connectionName` must be the map key such as\n`shared_teams`, not the GUID. The GUID belongs only inside the\n`connectionReferences[connector].connectionName` value. If an existing flow uses\nthe same connectors, you may also copy its `properties.connectionReferences`\nfrom `get_live_flow`.\n\n---\n\n## 3. Build the Flow Definition\n\nConstruct the definition object. See [flow-schema.md](references\u002Fflow-schema.md)\nfor the full schema and these action pattern references for copy-paste templates:\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n\n```python\ndefinition = {\n    \"$schema\": \"https:\u002F\u002Fschema.management.azure.com\u002Fproviders\u002FMicrosoft.Logic\u002Fschemas\u002F2016-06-01\u002Fworkflowdefinition.json#\",\n    \"contentVersion\": \"1.0.0.0\",\n    \"triggers\": { ... },   # see trigger-types.md \u002F build-patterns.md\n    \"actions\": { ... }     # see ACTION-PATTERNS-*.md \u002F build-patterns.md\n}\n```\n\n> See [build-patterns.md](references\u002Fbuild-patterns.md) for complete, ready-to-use\n> flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.\n\n### Discover connector operations before guessing JSON\n\nFor connector-backed triggers\u002Factions, prefer the live connector describer over\nhand-written shapes. It can return authored hints, canonical examples, variant\nkeys, inputs\u002Foutputs, and dynamic metadata pointers.\n\n```python\n# Search across connectors when you know the user's intent but not the API.\nmatches = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    search=\"send email\",\n    top=5)\n\n# Describe a specific operation before copying an exampleDefinition.\nop = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_office365\",\n    operationId=\"SendEmailV2\")\nprint(op.get(\"hint\"))\n```\n\nWhen an operation has multiple authored variants, request the variant the flow\nneeds:\n\n```python\nteams_chat = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_teams\",\n    operationId=\"PostMessageToConversation\",\n    variant=\"flowbot_chat\")\n```\n\nWhen the operation description says a parameter has dynamic options or dynamic\nproperties, call the indicated next tool:\n\n```python\nsp_op = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    operationId=\"GetItems\")\n\nsites = mcp(\"get_live_dynamic_options\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"dataset\",\n    dynamicMetadata=sp_op[\"dynamicParameters\"][\"dataset\"])\n\nfields = mcp(\"get_live_dynamic_properties\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"item\",\n    parameters={\"dataset\": \"\u003Csite-url>\", \"table\": \"\u003Clist-id>\"},\n    dynamicMetadata=sp_op[\"dynamicProperties\"][\"item\"])\n```\n\nUse dynamic options for dropdown IDs such as SharePoint sites\u002Flists and Teams\nteams\u002Fchannels. Use dynamic properties for schema\u002Ffield shapes such as\nSharePoint list item columns.\n\n---\n\n## 4. Deploy (Create or Update)\n\n`update_live_flow` handles both creation and updates in a single tool.\n\n### Create a new flow (no existing flow)\n\nOmit `flowName` — the server generates a new GUID and creates via PUT:\n\n```python\ndefinition[\"description\"] = \"Weekly SharePoint → Teams notification flow, built by agent\"\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    # flowName omitted → creates a new flow\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Create failed:\", result[\"error\"])\nelse:\n    # Capture the new flow ID for subsequent steps\n    FLOW_ID = result[\"created\"]\n    print(f\"✅ Flow created: {FLOW_ID}\")\n```\n\n### Update an existing flow\n\nProvide `flowName` to PATCH:\n\n```python\ndefinition[\"description\"] = (\n    \"Updated by agent on \" + __import__('datetime').datetime.utcnow().isoformat()\n)\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    flowName=FLOW_ID,\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"My Updated Flow\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Update failed:\", result[\"error\"])\nelse:\n    print(\"Update succeeded:\", result)\n```\n\n> ⚠️ `update_live_flow` always returns an `error` key.\n> `null` (Python `None`) means success — do not treat the presence of the key as failure.\n>\n> ⚠️ Flow description lives at `definition[\"description\"]`. The current server\n> appends `#flowstudio-mcp` for usage tracking. Do not pass a top-level\n> `description` argument unless `tool_search` shows one in the active schema.\n\n### Common deployment errors\n\n| Error message (contains) | Cause | Fix |\n|---|---|---|\n| `missing from connectionReferences` | An action's `host.connectionName` references a key that doesn't exist in the `connectionReferences` map | Ensure `host.connectionName` uses the **key** from `connectionReferences` (e.g. `shared_teams`), not the raw GUID |\n| `ConnectionAuthorizationFailed` \u002F 403 | The connection GUID belongs to another user or is not authorized | Re-run Step 2a and use a connection owned by the current `x-api-key` user |\n| `InvalidTemplate` \u002F `InvalidDefinition` | Syntax error in the definition JSON | Check `runAfter` chains, expression syntax, and action type spelling |\n| `ConnectionNotConfigured` | A connector action exists but the connection GUID is invalid or expired | Re-check `list_live_connections` for a fresh GUID |\n\n---\n\n## 5. Verify the Deployment\n\n```python\ncheck = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\n\n# Confirm state\nprint(\"State:\", check[\"properties\"][\"state\"])  # Should be \"Started\"\n# If state is \"Stopped\", use set_live_flow_state — NOT update_live_flow\n# mcp(\"set_live_flow_state\", environmentName=ENV, flowName=FLOW_ID, state=\"Started\")\n\n# Confirm the action we added is there\nacts = check[\"properties\"][\"definition\"][\"actions\"]\nprint(\"Actions:\", list(acts.keys()))\n```\n\n---\n\n## 6. Test the Flow\n\n> **MANDATORY**: Before triggering any test run, **ask the user for confirmation**.\n> Running a flow has real side effects — it may send emails, post Teams messages,\n> write to SharePoint, start approvals, or call external APIs. Explain what the\n> flow will do and wait for explicit approval before calling `trigger_live_flow`\n> or `resubmit_live_flow_run`.\n\n### Updated flows (have prior runs) — ANY trigger type\n\n> **Use `resubmit_live_flow_run` first.** It works for EVERY trigger type —\n> Recurrence, SharePoint, connector webhooks, Button, and HTTP. It replays\n> the original trigger payload. Do NOT ask the user to manually trigger the\n> flow or wait for the next scheduled run.\n\n```python\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs:\n    # Works for Recurrence, SharePoint, connector triggers — not just HTTP\n    result = mcp(\"resubmit_live_flow_run\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    print(result)   # {\"resubmitted\": true, \"triggerName\": \"...\"}\n```\n\n### HTTP, Button, and PowerApps flows — custom test payload\n\nOnly use `trigger_live_flow` when you need to send a **different** payload\nthan the original run. For verifying a fix, `resubmit_live_flow_run` is\nbetter because it uses the exact data that caused the failure.\n\n```python\ndefn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\ntriggers = defn[\"properties\"][\"definition\"][\"triggers\"]\nmanual = next(iter(triggers.values()))\nprint(\"Expected body:\", manual.get(\"inputs\", {}).get(\"schema\"))\n\nresult = mcp(\"trigger_live_flow\",\n    environmentName=ENV, flowName=FLOW_ID,\n    body={\"name\": \"Test\", \"value\": 1})\nprint(f\"Status: {result['responseStatus']}, via: {result['invocation']}\")\nprint(result.get(\"warning\"))   # set when a required input was missing: the run still ran, with null\n```\n\n### Brand-new non-HTTP flows\n\nA brand-new **Recurrence** flow needs no workaround: deploy it, then run it\nimmediately with `trigger_live_flow` and no `body` — same as the portal's\n\"Run flow\" button. A body is refused; scheduled triggers take no inputs.\n\nA brand-new **connector-triggered** flow (SharePoint, webhooks) has no prior\nruns and cannot fire without a real source event. Deploy with a temporary\nHTTP trigger, test the actions, then swap to the production trigger:\n\n```python\nproduction_trigger = definition[\"triggers\"]\ndefinition[\"triggers\"] = {\n    \"manual\": {\"type\": \"Request\", \"kind\": \"Http\", \"inputs\": {\"schema\": {}}}\n}\nresult = mcp(\"update_live_flow\", environmentName=ENV,\n    flowName=FLOW_ID,       # omit if creating new\n    definition=definition, connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\")\nFLOW_ID = FLOW_ID or result[\"flowName\"]\n\nmcp(\"trigger_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    body={\"sample\": \"payload\"})\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs[0][\"status\"] == \"Failed\":\n    err = mcp(\"get_live_flow_run_error\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    raise Exception(err[\"failedActions\"][-1])\n\ndefinition[\"triggers\"] = production_trigger\nmcp(\"update_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    definition=definition, connectionReferences=connection_references)\n```\n\nThe trigger is only the entry point; testing through HTTP still exercises the\nsame actions. If actions use `triggerBody()` or `triggerOutputs()`, pass a\nrepresentative `body` shaped like the production trigger payload.\n\n---\n\n## Gotchas\n\n| Mistake | Consequence | Prevention |\n|---|---|---|\n| Missing `connectionReferences` in deploy | 400 \"Supply connectionReferences\" | Always call `list_live_connections` first |\n| `\"operationOptions\"` missing on Foreach | Parallel execution, race conditions on writes | Always add `\"Sequential\"` |\n| `union(old_data, new_data)` | Old values override new (first-wins) | Use `union(new_data, old_data)` |\n| `split()` on potentially-null string | `InvalidTemplate` crash | Wrap with `coalesce(field, '')` |\n| Checking `result[\"error\"]` exists | Always present; true error is `!= null` | Use `result.get(\"error\") is not None` |\n| Flow deployed but state is \"Stopped\" | Flow won't run on schedule | Call `set_live_flow_state` with `state: \"Started\"` — do **not** use `update_live_flow` for state changes |\n| Teams \"Chat with Flow bot\" recipient as object | 400 `GraphUserDetailNotFound` | Use plain string with trailing semicolon (see below) |\n| Copilot\u002FSkills flow not in a solution | Copilot Studio may not discover it as an agent tool | After deploy, call `add_live_flow_to_solution` with the target `solutionId` |\n| Button\u002FSkills trigger used for MCP testing | Runs even when a required input is missing (null) | Pass inputs in `trigger_live_flow` `body`; on `warning`, cancel and retry with the full body |\n| Connector action missing `metadata.operationMetadataId` | Designer\u002Frun-only UI can behave inconsistently | Preserve existing IDs; add stable GUIDs for new connector actions |\n| Placeholder Excel `scriptId` | Dynamic validation fails at save time | Resolve the real Office Script ID before deploying |\n| SharePoint `PatchItem` omits required fields | Save can fail even if the field is not changing | Echo unchanged required fields such as `item\u002FTitle` |\n| Copilot Studio connector calls a draft agent | Connector invocation can fail or hit stale behavior | Publish the agent before testing\u002Fresubmitting the flow |\n\n### Teams `PostMessageToConversation` — Recipient Formats\n\nThe `body\u002Frecipient` parameter format depends on the `location` value:\n\n| Location | `body\u002Frecipient` format | Example |\n|---|---|---|\n| **Chat with Flow bot** | Plain email string with **trailing semicolon** | `\"user@contoso.com;\"` |\n| **Channel** | Object with `groupId` and `channelId` | `{\"groupId\": \"...\", \"channelId\": \"...\"}` |\n\n> **Common mistake**: passing `{\"to\": \"user@contoso.com\"}` for \"Chat with Flow bot\"\n> returns a 400 `GraphUserDetailNotFound` error. The API expects a plain string.\n\n---\n\n## Reference Files\n\n- [flow-schema.md](references\u002Fflow-schema.md) — Full flow definition JSON schema\n- [trigger-types.md](references\u002Ftrigger-types.md) — Trigger type templates\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n- [build-patterns.md](references\u002Fbuild-patterns.md) — Complete flow definition templates (Recurrence+SP+Teams, HTTP trigger)\n\n## Related Skills\n\n- `flowstudio-power-automate-mcp` — Core connection setup and tool reference\n- `flowstudio-power-automate-debug` — Debug failing flows after deployment\n",{"name":5,"description":7},"main","5269f7ea2d6c3a9bfda5ed878b6726cf509121fd","skills\u002Fflowstudio-power-automate-build",5354,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot","https:\u002F\u002Fawesome-copilot.github.com\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-14 05:37:52",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add github\u002Fawesome-copilot --skill flowstudio-power-automate-build",{"tool":73,"command":74},"bunx","bunx skills add github\u002Fawesome-copilot --skill flowstudio-power-automate-build",{"tool":76,"command":77},"pnpm","pnpm dlx skills add github\u002Fawesome-copilot --skill flowstudio-power-automate-build","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002FSKILL.md",true,[81,87,91,95,99,103,107],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"agents\u002Fopenai.yaml","REFERENCE","参考文档",166,"https:\u002F\u002Fgithub.com\u002Ftdortman\u002Fdotfiles\u002Fblob\u002Fmain\u002Fhome\u002Fdot_agents\u002Fskills\u002Fto-questionnaire\u002Fagents\u002Fopenai.yaml",{"path":88,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":89,"sourceHtmlUrl":90},"references\u002Faction-patterns-connectors.md",18400,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Faction-patterns-connectors.md",{"path":92,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":93,"sourceHtmlUrl":94},"references\u002Faction-patterns-core.md",16611,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Faction-patterns-core.md",{"path":96,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":97,"sourceHtmlUrl":98},"references\u002Faction-patterns-data.md",19019,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Faction-patterns-data.md",{"path":100,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":101,"sourceHtmlUrl":102},"references\u002Fbuild-patterns.md",2726,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Fbuild-patterns.md",{"path":104,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":105,"sourceHtmlUrl":106},"references\u002Fflow-schema.md",5208,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Fflow-schema.md",{"path":108,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":109,"sourceHtmlUrl":110},"references\u002Ftrigger-types.md",5463,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fflowstudio-power-automate-build\u002Freferences\u002Ftrigger-types.md",[112,142,170,200,234,250],{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":122,"publishedAt":52},"01M70KXZNX9ES38N2A8M58ZZMZ","supabase-rls-policies","Write, review, and test Supabase Row Level Security (RLS) policies so that one user cannot read or change another user's rows. Use when creating or changing tables, policies, views, or security definer functions in a Supabase project, when reviewing a migration that touches RLS, or when asked to prove user isolation with pgTAP tests that sign in as two users.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fsupabase-rls-policies\u002FSKILL.md",[118,121],{"categoryNo":119,"categoryName":120,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[123,124,125,126,127,34,128,129,130,131,132,133,134,135,136,137,138,139,140,141],"supabase","rls","supabase rls","supabase rls policies","project","review","change","read","write","security","isolation","tables","as","tests","prove","use","users","functions","with",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":149,"publishedAt":52},"01M70KWA5YWXDV6V8DZ19E3T2Y","skill-distribution-audit","Audit a skill collection before release or investigate installer omissions, archived\u002Ftemplate leakage, duplicate identities, and manifest drift. Reconcile the intended public source set, distribution manifest, and actual discovery output for a specified consumer version. Includes a deterministic set-comparison helper.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fskill-distribution-audit\u002FSKILL.md",[148],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169],"distribution","skill distribution audit","audit","SET","deterministic","installer","for","discovery","comparison","helper","manifest","version","collection","drift","output","investigate","duplicate","template","release","reconcile",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":182,"publishedAt":52},"01M70KCJPFVW7PPQ49CC5R8JGK","logicapps-custom-code-net10-migration","Migrate Azure Logic Apps Standard local-function custom-code projects from .NET 8 to .NET 10. Use for legacy Logic Apps custom-code workspace upgrades, project\u002Fpackage configuration, custom-worker settings, publication, and integrated VS Code debugging. Not for ordinary .NET applications, standalone Azure Functions, Consumption workflows, or cloud deployment.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":180,"taxonomyTypeDesc":181},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[183,184,185,186,187,188,156,127,189,190,191,192,193,194,195,138,196,197,198,199],"custom","code","logicapps custom code net10 migration","migration","projects","standalone","deployment","applications","local","azure","worker","upgrades","package","apps","Legacy","debugging","workflows",{"skillNo":201,"name":202,"nameZh":6,"description":203,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":204,"sourceHtmlUrl":205,"categories":206,"keywords":211,"publishedAt":52},"01M6AEBN37RQMXJ3298PEY7PG1","winmd-api-search","Find and explore Windows desktop APIs. Use when building features that need platform capabilities — camera, file access, notifications, UI controls, AI\u002FML, sensors, networking, etc. Discovers the right API for a task and retrieves full type details (methods, properties, events, enumeration values).","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FSKILL.md",[207,210],{"categoryNo":208,"categoryName":209,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":178,"categoryName":179,"taxonomyType":180,"taxonomyTypeDesc":181},[212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,34,227,228,229,230,231,156,232,233],"winmd api search","search","api","windows","desktop","file access","enumeration","ui","ml","file","networking","capabilities","notifications","explore","access","features","full","camera","events","platform","methods","controls",{"skillNo":235,"name":236,"nameZh":6,"description":237,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":238,"licenseFileUrl":239,"sourceHtmlUrl":240,"categories":241,"keywords":247,"publishedAt":52},"01M6AE571R3SC1ZGE202B3NB5S","resemble-detect","Deepfake detection and media safety — detect AI-generated audio, images, video, and text, trace synthesis sources, apply watermarks, verify speaker identity, and analyze media intelligence using Resemble AI","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FSKILL.md",[242,243,246],{"categoryNo":208,"categoryName":209,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":244,"categoryName":245,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[248,153,221,44,249],"resemble detect","identity",{"skillNo":251,"name":252,"nameZh":6,"description":253,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":238,"licenseFileUrl":254,"sourceHtmlUrl":255,"categories":256,"keywords":261,"publishedAt":52},"01M6AE30BSK2HCY4TQQ22Z8JRD","quality-playbook","Run a complete quality engineering audit on any codebase. Derives behavioral requirements from the code, generates spec-traced functional tests, runs a three-pass code review with regression tests, executes a multi-model spec audit (Council of Three), and produces a consolidated bug report with TDD-verified patches. Finds the 35% of real defects that structural code review alone cannot catch. Works with any language. Trigger on 'quality playbook', 'spec audit', 'Council of Three', 'fitness-to-purpose', or 'coverage theater'.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FSKILL.md",[257,260],{"categoryNo":258,"categoryName":259,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[262,263,264,265,184,128,9,152,266,267,44,268,269,270,271,272,273,274,275,276,277,278,136,279,280,281,282],"playbook","quality playbook","quality","code review","tdd","run","report","spec","bug report","council","engineering","functional","spec audit","bug","verified","multi-model","three","coverage","model","regression","structural"]