@uipath/skills 1.199.0-preview.106 → 1.199.0-preview.218

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -233,8 +233,6 @@
233
233
  "agenthub mcp update",
234
234
  "agenthub mcp-tools",
235
235
  "agenthub mcp-tools candidates",
236
- "agenthub mcp-tools create-is-activity",
237
- "agenthub mcp-tools create-raw",
238
236
  "agenthub mcp-tools create-resource",
239
237
  "agenthub mcp-tools delete",
240
238
  "agenthub mcp-tools disable",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/skills",
3
- "version": "1.199.0-preview.106",
3
+ "version": "1.199.0-preview.218",
4
4
  "description": "UiPath agent skills for Claude Code, Codex, Cursor, Copilot, Gemini and OpenCode — RPA, UI automation, UI testing, coded agents/apps/workflows, and troubleshooting. Distributed as the UiPath Claude Code plugin.",
5
5
  "author": {
6
6
  "name": "UiPath"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: uipath-mcp-servers
3
- description: "UiPath AgentHub MCP server registration + tool authoring via `uip agenthub mcp` (six server types: uipath / coded / command / remote / platform / swagger) and `uip agenthub mcp-tools` (three tool kinds: is-activity / resource / raw on `uipath`-type servers). For Integration Service activity authoring→load `references/is-activity-workflow.md`. For Python MCP servers / coded-agent integration→uipath-agents. For raw IS CLI→uipath-platform."
3
+ description: "UiPath AgentHub MCP server registration + resource-tool authoring via `uip agenthub mcp` (six server types: uipath / coded / command / remote / platform / swagger) and `uip agenthub mcp-tools` on `uipath`-type servers. For Python MCP servers / coded-agent integration→uipath-agents."
4
4
  allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
5
5
  ---
6
6
 
@@ -13,9 +13,8 @@ Register AgentHub MCP servers via `uip agenthub mcp`. Author tools on `uipath`-t
13
13
  ## When to Use This Skill
14
14
 
15
15
  - Create / update / delete / refresh / list / get an AgentHub MCP server (any of: `uipath`, `coded`, `command`, `remote`, `swagger`, `platform`).
16
- - Author / list / get / enable / disable / delete tools on a `uipath`-type server (`is-activity`, `resource`, `raw`).
17
- - **For `is-activity` tools (Integration Service connector activities), load [references/is-activity-workflow.md](references/is-activity-workflow.md) end-to-end before authoring.** It owns the Pre-flight, cascade, `designTimeLookups`, `ActivityMetadata` schema, and connector-specific troubleshooting.
18
- - Skip: Python MCP server implementation (FastMCP / `@uipath/mcp`) → `uipath-agents`. Raw IS CLI outside MCP tooling → `uipath-platform`.
16
+ - Author resource tools on a `uipath`-type server; list / get / enable / disable / delete its tools.
17
+ - Skip: Python MCP server implementation (FastMCP / `@uipath/mcp`) → `uipath-agents`.
19
18
 
20
19
  ## Trust the CLI
21
20
 
@@ -23,8 +22,8 @@ The CLI is the source of truth for shapes and flags. Use it instead of guessing:
23
22
 
24
23
  - `uip agenthub mcp create <type> --print-schema --output json` — payload shape for any server type.
25
24
  - `uip agenthub mcp template <type> --output json` — ready-to-edit `--file` skeleton.
26
- - `uip agenthub mcp-tools template <kind> --output json` — tool payload skeleton (is-activity / resource / raw).
27
- - `uip agenthub mcp-tools candidates --category <kind> --output json` — discover bindable targets. `<kind>` ∈ `automation | agent | agentic-process | api-workflow | is-activity`.
25
+ - `uip agenthub mcp-tools template resource --output json` — resource-tool payload skeleton.
26
+ - `uip agenthub mcp-tools candidates --category <kind> --output json` — discover bindable targets. `<kind>` ∈ `automation | agent | agentic-process | api-workflow`.
28
27
  - `--output-filter <JMESPath>` on every command — extract specific fields without walking JSON by hand (e.g. `--output-filter "Data.items[].slug" --output plain`).
29
28
  - `--dry-run` on every mutating call — resolve and inspect the body before POST. Note: `--dry-run` skips some server-side validation, so a clean dry-run is not a guaranteed real POST.
30
29
 
@@ -41,19 +40,17 @@ These are the things the CLI does not advertise in `--help`.
41
40
  4. **`refresh-tools` behavior depends on server type.**
42
41
  - `coded` / `command` — async, returns HTTP 202 + runtime id. Surface the runtime id; never claim refreshed before a follow-up `mcp-tools list --mcp <slug>` confirms.
43
42
  - `remote` / `platform` / `swagger` — sync, returns 200 after a synchronous fetch+upsert.
44
- - `uipath` / `selfhosted` — rejected locally; tools are manually authored via `mcp-tools create-*`. CLI emits a `NextCommand` hint to author instead.
43
+ - `uipath` / `selfhosted` — rejected locally; resource tools are manually authored via `mcp-tools create-resource`. CLI emits a `NextCommand` hint to author instead.
45
44
 
46
45
  5. **`mcp delete` looks up by slug, not GUID.** Passing a GUID returns 404.
47
46
 
48
- 6. **For any `is-activity` tool, read [references/is-activity-workflow.md](references/is-activity-workflow.md) end-to-end before any CLI call.** It owns the cascade-asking gate, the action-triggered platform-IS reads, the `ActivityMetadata` schema, and the `inputSchema` / `designTimeLookups` rules. IS metadata authored from memory passes `--dry-run` but fails at runtime — do not skip the reference. `Reason: IsActivityNotAvailable` from ANY is-activity verb → STOP immediately: no further is-activity calls (no create attempt "to confirm" — the error covers every verb), no `--force` without explicit user approval; the gate follows the payload — an IS-activity payload (`type: 1` + `processType: Api`) via `create-raw` / `create-resource` / `update --file`/`--body` is gated identically; offer `resource` / `raw` instead (genuinely different kinds, not the same payload re-verbed — reference §Availability).
49
-
50
47
  ## Server Types
51
48
 
52
49
  `uip agenthub mcp create` takes six type subcommands. All share `--name <display>`, `--slug <kebab>`, `--description`, `--version`, `--file`/`--body`/`--print-schema`, `--dry-run`, `--folder-path`/`--folder-key`, `--tenant`, `--login-validity`. The differentiating flag picks the integration shape:
53
50
 
54
51
  | Type | Differentiating flag | When to use | Tool surface |
55
52
  |------|---------------------|-------------|--------------|
56
- | `uipath` | _(none)_ | AgentHub-hosted server you'll fill with `mcp-tools create-*`. | Authored via `uip agenthub mcp-tools create-*`. `refresh-tools` rejected. <!-- uip-check-skip --> |
53
+ | `uipath` | _(none)_ | AgentHub-hosted server you'll fill with resource tools. | Authored via `uip agenthub mcp-tools create-resource`. `refresh-tools` rejected. |
57
54
  | `coded` | `--process-key <key>` (+ `--folder-key` for the process) | Wrap an existing coded-agent process (published to Orchestrator) as an MCP server. | Discovered via `refresh-tools` (async 202). |
58
55
  | `command` | `--command <cmd>` + `--arg <arg>` (repeatable) + `--env <k=v>` (repeatable) | Spawn a local subprocess as an MCP server. | Discovered via `refresh-tools` (async 202). |
59
56
  | `remote` | `--uri <url>` + `--header <k=v>` (repeatable) + `--use-relay` | Point at an existing HTTP MCP server. Bearer/header values can be Orchestrator asset references; `AssetReferenceSubstitutor` resolves them at runtime via the caller's token + folder context. Do NOT invent a credential-store syntax. | Discovered via `refresh-tools` (sync 200). |
@@ -66,15 +63,13 @@ Headers/auth on `remote` and `swagger` are payload fields, not scalar flags. Rea
66
63
 
67
64
  `mcp template <type>` also accepts `process-assistant` and `selfhosted` — these have templates but NO `create` subcommand (backend enum only; skip).
68
65
 
69
- ## Tool Kinds (`uipath`-type servers only)
66
+ ## Resource Tools (`uipath`-type servers only)
70
67
 
71
- `uip agenthub mcp-tools create-{is-activity | resource | raw}`. Shared flags: `--mcp <slug>` (parent server), `--name`, `--description`, `--target-identifier <guid>` / `--target-name <name>` (resolve target via RCS — only for non-`activity` categories), `--folder-key <guid>` / `--folder-path <name>` (MCP server folder context), `--target-folder-key <guid>` / `--target-folder-path <name>` (any kind — the target's folder — IS connection / Orchestrator resource / raw payload target — when it differs from the server's; resolves to the tool's `targetFolderKey`; never both; omit to default to the candidate's folder (`--target-name`) or the server folder; the explicit flag wins, including over a `--file`/`--body` payload field), `--category`, `--input-schema`, `--output-schema`, `--metadata`, `--continue-on-error` (default) / `--fail-fast`, `--file`/`--body`, `--dry-run`. Differ in metadata shape, discovery path, and validation strictness.
68
+ Run `uip agenthub mcp-tools create-resource`. Flags: `--mcp <slug>` (parent server), `--name`, `--description`, `--target-identifier <guid>` / `--target-name <name>` (resolve target via RCS), `--folder-key <guid>` / `--folder-path <name>` (MCP server folder context), `--target-folder-key <guid>` / `--target-folder-path <name>` (the Orchestrator resource's folder when it differs from the server's; resolves to the tool's `targetFolderKey`; never both; omit to default to the candidate's folder (`--target-name`) or the server folder; the explicit flag wins, including over a `--file`/`--body` payload field), `--category`, `--input-schema`, `--output-schema`, `--metadata`, `--continue-on-error` (default) / `--fail-fast`, `--file`/`--body`, `--dry-run`.
72
69
 
73
70
  | Kind | Discovery | Validation | When to use |
74
71
  |------|-----------|------------|-------------|
75
- | `is-activity` | `mcp-tools candidates --category is-activity` + `is resources describe` | Connector schema | Wrap an Integration Service connector activity as an MCP tool. **Load [references/is-activity-workflow.md](references/is-activity-workflow.md) end-to-end** — extra Critical Rules, Pre-flight, `ActivityMetadata` schema, and IS-specific troubleshooting apply. Rolling out: unavailable environments fail with `Reason: IsActivityNotAvailable` — follow the reference's §Availability (stop; offer `resource` / `raw`). |
76
72
  | `resource` | `mcp-tools candidates --category <kind>` (kind ∈ `automation` / `agent` / `agentic-process` / `api-workflow`) | Resource schema | Bind an Orchestrator resource. Pass `--target-identifier <resource-id>`. Read metadata shape from `mcp-tools template resource --output json`. `candidates` is tenant-wide — each item carries its `folder {key, name}`; present the folder alongside the name when the user picks. `--target-name` lookup searches the server folder by default; resource in a different folder → pass `--target-folder-path` / `--target-folder-key` (scopes the lookup AND sets the tool's `targetFolderKey`); with `--target-identifier`, pass the same flags when the resource's folder differs from the server's. |
77
- | `raw` | None | None | Free-form JSON tool — caller owns correctness end-to-end. No discovery, no schema validation, no reference-value labeling. Read the skeleton from `mcp-tools template raw --output json`. |
78
73
 
79
74
  Stringify `--metadata` / `--input-schema` / `--output-schema` as scalars (not `--file`). Build each JSON in a file and pass it as `--metadata "$(jq -c . metadata.json)"` (likewise input/output schema) — do **not** assemble multi-KB JSON inline in the command. Pass `--output-schema "{}"` when the underlying target has no response fields — empty string is rejected with `Unexpected end of JSON input`.
80
75
 
@@ -89,5 +84,3 @@ Other `mcp-tools` verbs (`list --mcp <slug>`, `get`, `enable`, `disable`, `delet
89
84
  - **Slug rejected with validation error** — backend enforces `^[a-z0-9-]+$`, length 3-50 (Critical Rule 1).
90
85
  - **`mcp delete <guid>` returns 404** — `mcp delete` looks up by slug, not GUID (Critical Rule 5).
91
86
  - **`refresh-tools` returns 202 with a runtime id** — `coded` / `command` refreshes are async (Critical Rule 4). Surface the runtime id; verify via follow-up `mcp-tools list --mcp <slug>`.
92
-
93
- Tool-kind-specific troubleshooting lives with the workflow that owns it — IS-activity troubleshooting is in [references/is-activity-workflow.md](references/is-activity-workflow.md).
@@ -138,7 +138,7 @@ High-level view of what each specialist owns. **Do not describe internal flows o
138
138
  | `uipath-platform` | Auth (`uip login`), Orchestrator (folders, processes, jobs, machines, users, roles), resources (assets, queues, storage buckets + bucket files, libraries, webhooks, triggers), Integration Service (connectors, connections, activities, IS triggers), Data Fabric entities/records/files/choice-sets (`uip df`), traces, licensing | Yes (auth hub) | **Yes** — for non-solution single packages and Orchestrator-side post-deploy ops |
139
139
  | `uipath-ixp` | Document Understanding / IXP — extraction from semi-structured documents (invoices, forms): taxonomy, model, classify / extract / validate. Standalone project, or the extraction step a primary consumes | Yes (`uip login`) | **Partial** — model publish/tag via `uip ixp`; consumed by the host project |
140
140
  | `uipath-connector-builder` | Integration Service **custom connector** authoring (REST+JSON) on disk via `uip is connectors builder` — build a connector when the catalog has none for a required integration (needed by API Workflows / Maestro / Agents; RPA can call the API directly instead) | Yes (`uip login`) | **Yes** — import/publish is deployment (`uip is connectors`) |
141
- | `uipath-mcp-servers` | UiPath AgentHub MCP server registration (6 types: `uipath`, `coded`, `command`, `remote`, `swagger`, `platform`) and tool authoring on `uipath`-type servers (3 kinds: `is-activity`, `resource`, `raw`). Wraps IS connector activities, Orchestrator resources, external HTTP MCP endpoints, OpenAPI specs, published coded agents, local subprocess commands, or first-party UiPath services as MCP tools. NOT for FastMCP / Python `mcp` SDK work. | Yes (`uip login`) | **Yes** — registration is deployment (posts directly to AgentHub) |
141
+ | `uipath-mcp-servers` | UiPath AgentHub MCP server registration (6 types: `uipath`, `coded`, `command`, `remote`, `swagger`, `platform`) and resource-tool authoring on `uipath`-type servers (`automation`, `agent`, `agentic-process`, `api-workflow`). Wraps Orchestrator resources, external HTTP MCP endpoints, OpenAPI specs, published coded agents, local subprocess commands, or first-party UiPath services as MCP tools. NOT for FastMCP / Python `mcp` SDK work. | Yes (`uip login`) | **Yes** — registration is deployment (posts directly to AgentHub) |
142
142
  | `uipath-solution` | `uip solution` lifecycle (init, pack, publish, deploy, activate) for `.uipx` solutions. Runs as the final skill in PDD-driven flows (deploy of `.uipx` solutions). | Yes (`uip login`) | **Yes** — for multi-project Solution (`.uipx`) deploys |
143
143
 
144
144
  ## Reference Navigation
@@ -92,7 +92,7 @@ Orchestrator deploy of the wrapping `.uipx` solution requires `uipath-solution`.
92
92
 
93
93
  ## Pattern 6 — Build an AgentHub MCP server
94
94
 
95
- **When it applies:** the request is to register an AgentHub MCP server that wraps a coded agent or uses Orchestrator-asset-backed auth that does not exist yet. Pure `uipath-mcp-servers` work — `uipath` / `command` / `platform` servers, `remote`/`swagger` with auth assets already in place, or any `is-activity` tool authoring against existing IS connections — is single-skill; go straight to `uipath-mcp-servers`.
95
+ **When it applies:** the request is to register an AgentHub MCP server that wraps a coded agent or uses Orchestrator-asset-backed auth that does not exist yet. Pure `uipath-mcp-servers` work — `uipath` servers with resource tools, `command` / `platform` servers, or `remote` / `swagger` servers with auth assets already in place — is single-skill; go straight to `uipath-mcp-servers`.
96
96
 
97
97
  Wrapping a not-yet-built coded agent (server type `coded`):
98
98
 
@@ -108,8 +108,6 @@ Orchestrator assets needed for `remote` / `swagger` Bearer / header substitution
108
108
  2. uipath-mcp-servers → register the server with asset-substituted headers
109
109
  ```
110
110
 
111
- Missing IS connections are **not** a `uipath-platform` prereq — IS connections are created interactively in the Integration Service UI via OAuth, not by the CLI.
112
-
113
111
  ## Pattern routing for PDD-driven lane
114
112
 
115
113
  When deriving tasks from an SDD, the planner picks a pattern based on the SDD's project list:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: uipath-test
3
- description: "UiPath Test Manager — manage test projects, cases, sets, executions; generate reports. For Orchestrator→uipath-platform. For test automation→uipath-rpa."
3
+ description: "UiPath Test Manager — manage test projects, cases, sets, executions; generate reports; package and run external Playwright test suites. For Orchestrator→uipath-platform. For Studio/RPA test automation authoring→uipath-rpa."
4
4
  allowed-tools: Bash, Read, Write, Glob, Grep
5
5
  user-invocable: true
6
6
  ---
@@ -29,6 +29,7 @@ UiPath Test Manager is a web application that manages the testing lifecycle of p
29
29
  - **Test case logs** - Logs of a **test case** in an execution. A **testcase** can be navigated from **testcaselogs**.
30
30
  - **Test step logs** — Step-level logs within a **test case log**.
31
31
  - **Test case log assertions** - Assertion steps of a test case log in an execution.
32
+ - **External (Playwright) test packages** - A Playwright suite packaged as an external test package and uploaded to Orchestrator. Ingestion auto-creates one test case per Playwright test (no link step) and labels each with `PW_Tag_*`, `PW_Project_*`, `PW_Suite_*`, `PW_File_*`. These run on serverless cloud runtimes — see [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md).
32
33
 
33
34
  CLI tool for UiPath Test Manager (`uip tm`). Use `uip tm --help` and `uip tm <command> <subcommand> --help` to discover commands and options. **Always pass `--output json`** on every `uip` command.
34
35
 
@@ -85,7 +86,7 @@ Common `uip tm` commands organized by resource type.
85
86
  | `uip tm testcases steps delete --project-key <PROJECT_KEY> --step-id <UUID> --yes` | Delete a step. |
86
87
  | `uip tm testcases list-result-history --project-key <PROJECT_KEY> --test-case-id <TEST_CASE_ID>` | List test case log result history for a specific test case. Optional `--only-failed`, `--filter`, `--limit`, `--offset`. |
87
88
  | `uip tm testcases run --project-key <PROJECT_KEY> --test-case-id <TEST_CASE_ID>` | Start a new execution for one or more test cases. **Uses `--test-case-id <UUID>` (space-separated for multiple).** Optional `--async`, `--name`, `--folder-key`, `--robot-user-key`, `--machine-key`. |
88
- | `uip tm testcases add --test-set-key <TEST_SET_KEY> --test-case-keys <KEY1,KEY2,...>` | Add test cases to a test set (comma-separated keys). |
89
+ | `uip tm testcases add --test-set-key <TEST_SET_KEY> (--test-case-keys <KEY1> <KEY2> … \| --labels <Label1> <Label2> …)` | Add test cases to a test set — by explicit keys, OR every test case carrying at least one of the given labels. Both selectors are variadic and **space-separated**: `--test-case-keys DEMO:1 DEMO:2`, `--labels PW_Tag_smoke "PW_Suite_Checkout flow"` (quote names containing spaces). Keys additionally accept the comma form (`DEMO:1,DEMO:2`); **labels do not** — `--labels A,B` is read as one label named `A,B` and matches nothing. Label matching is OR, exact and case-sensitive. The two selectors are mutually exclusive. |
89
90
  | `uip tm testcases remove --test-set-key <TEST_SET_KEY> --test-case-keys <KEY1,KEY2,...>` | Remove test cases from a test set (comma-separated keys). |
90
91
 
91
92
  > **Flag shapes for test case and step identifiers — do not interchange:**
@@ -103,10 +104,13 @@ Common `uip tm` commands organized by resource type.
103
104
  | `uip tm testsets update --test-set-key <TEST_SET_KEY> --name <TEST_SET_NAME>` | Update a test set name or description. |
104
105
  | `uip tm testsets delete --test-set-key <TEST_SET_KEY>` | Delete a test set by its key. |
105
106
  | `uip tm testsets list-testcases --project-key <PROJECT_KEY> --test-set-key <TEST_SET_KEY>` | List test cases assigned to a test set. |
106
- | `uip tm testsets run --test-set-key <TEST_SET_KEY>` | Run a test set and return the execution ID. Optional `--execution-type <automated\|manual\|mixed\|none>` (default `automated`), `--input-path <FILE>` for parameter overrides. |
107
+ | `uip tm testsets run --test-set-key <TEST_SET_KEY>` | Run a test set and return the execution ID. Optional `--execution-type <automated\|manual\|mixed\|none>` (default `automated`), `--input-path <FILE>` for parameter overrides. For Playwright test sets, optional `--playwright-projects <names...>` — see the note below. |
108
+ | `uip tm testsets playwright-context --test-set-key <TEST_SET_KEY>` | Probe whether a test set is a Playwright test set: returns `IsPlaywright` plus the available and selected Playwright project names. |
107
109
 
108
110
  > Keys use the format `PROJECT_KEY:NUMBER` (e.g., `INV:42`). To add or remove test cases in a test set, use `uip tm testcases add` / `uip tm testcases remove` — those verbs live under the `testcases` group, not under `testsets`.
109
111
 
112
+ > **Playwright test sets:** `--playwright-projects <names...>` (space-separated, case-sensitive `playwright.config` project names) runs only the selected projects and persists the selection on the test set. It requires every test case in the set to come from one Playwright package; unknown names fail fast listing the valid ones. Probe first with `playwright-context` and branch on `IsPlaywright`. Both need a Test Manager with Playwright support and a CLI carrying the external-package commands — [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md) opens with the check to run and what to do when they are absent.
113
+
110
114
  ### Executions Commands
111
115
 
112
116
  | Command | Purpose |
@@ -141,7 +145,7 @@ Common `uip tm` commands organized by resource type.
141
145
 
142
146
  | Command | Purpose |
143
147
  |---|---|
144
- | `uip tm report get --execution-id <EXECUTION_ID>` | Get a summary report for a completed test execution. Optional `--project-key`, `--test-set-key`, `--query`. |
148
+ | `uip tm report get --execution-id <EXECUTION_ID> (--project-key <KEY> \| --test-set-key <KEY>)` | Get a summary report for a completed test execution. One of `--project-key`/`--test-set-key` is required to identify the project (verified: passing only `--execution-id` exits with "Provide --project-key or --test-set-key"). |
145
149
 
146
150
  ### Attachment Commands
147
151
 
@@ -156,6 +160,14 @@ Common `uip tm` commands organized by resource type.
156
160
  |---|---|
157
161
  | `uip tm result download --execution-id <EXECUTION_ID>` | Download test execution results as JUnit XML. Optional `--project-key`, `--test-set-key`, `--result-path <DIR>`. |
158
162
 
163
+ ### Pack Commands (Playwright)
164
+
165
+ | Command | Purpose |
166
+ |---|---|
167
+ | `uip tm pack --project-path <dir> --type playwright --project-key <PROJECT_KEY> --name <PackageName> --package-version <ver> -o <out-dir>` | Pack a Playwright suite into a `.nupkg` external test package. Requires a lockfile and `@playwright/test` in the project. `--package-version` takes a NuGet/SemVer-style version — three numeric parts, optional prerelease suffix (`1.0.0`, `1.0.1-beta.1`); `1.0` or a non-numeric string is rejected. `--project-key` targets the Test Manager project where ingestion auto-creates the test cases; `--no-create-test-cases` skips that; `--dry-run` previews. Upload with `uip or packages upload <nupkg>`. |
168
+
169
+ > Packing is offline — no auth needed. The upload → ingestion → label-fill → run pipeline is in [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md).
170
+
159
171
  ### Wait Commands
160
172
 
161
173
  | Command | Purpose |
@@ -223,7 +235,7 @@ Object labels are tag-style metadata applied to Requirement, TestCase, TestSet,
223
235
  4. **Cap retries at 3** for any failing `uip` CLI command. After 3 failures, stop and report the error to the user (see Rule — never fall back to direct REST APIs).
224
236
  5. **Handle empty results** — if a list command returns an empty array, stop and inform the user rather than proceeding with a null key.
225
237
  6. **Confirm before delete** — always confirm the target resource key with the user before running any `delete` command. All delete commands require `--yes` (or `-y`) to proceed; omitting it exits without deleting.
226
- 7. **For operations requiring folder key** — use `uip or folders list -n <folder-name> --all --output json` (run `/uipath-platform` for folder management details).
238
+ 7. **For operations requiring folder key** — use `uip or folders list -n <folder-name> --all --output json` when the user named a folder; when picking one yourself, list without `--all` so you only get folders you are a member of (run `/uipath-platform` for folder management details).
227
239
  8. **Discover before assuming** — never guess automation names, folder keys, project IDs, or test case keys. Always run the matching `list` command first (e.g., `uip tm testcases list-automations`, `uip or folders list -n <folder-name> --all`).
228
240
  9. **Narrow `list` calls server-side when the user names an entity.** When the user provides a name, key, label, or tag, check `uip tm <resource> list --help` (or `uip or <resource> list --help`) for the narrowing flag the command exposes and pass it on the `list` call. Never list all results and filter client-side — it wastes tokens and misses paginated entries. Applies to every entity across `uip tm` and `uip or`.
229
241
  10. **Set default folder before any `run` command** — `uip tm testcases run` and `uip tm testsets run` both require a default Orchestrator folder on the project. Run `uip tm project set-default-folder --project-key <PROJECT_KEY> --folder-key <FOLDER_KEY> --output json` first. Get folder keys with `uip or folders list -n <folder-name> --all --output json`.
@@ -305,7 +317,8 @@ If the probe in Rule #2 shows singular subjects, the CLI predates the closed-ver
305
317
  | I want to... | Start here |
306
318
  |---|---|
307
319
  | **Generate a shareable test report** (tester or release manager view) | [references/test-result-report-guide.md](references/test-result-report-guide.md) |
308
- | **Publish a project and link it to a Test Manager test case** | [references/publish-and-link-guide.md](references/publish-and-link-guide.md) |
320
+ | **Publish a project and link it to a Test Manager test case** (Studio/RPA) | [references/publish-and-link-guide.md](references/publish-and-link-guide.md) |
321
+ | **Pack, ingest, and run a Playwright suite on serverless** (pack → upload → labels → run) | [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md) |
309
322
 
310
323
 
311
324
  ## Anti-patterns
@@ -313,3 +326,4 @@ If the probe in Rule #2 shows singular subjects, the CLI predates the closed-ver
313
326
  - **Do NOT proceed if authentication fails** — all Test Manager API calls require a valid bearer token. Fail fast rather than surfacing confusing 401 errors later.
314
327
  - **Do NOT skip the surface probe** (Critical Rule #2). On a pre-rename CLI, post-rename commands fail with `unknown command`; on a post-rename CLI, pre-rename commands fail the same way. The skill targets the post-rename surface and falls back per the [Pre-rename fallbacks](#pre-rename-fallbacks) table. Picking the wrong shape without probing burns a retry on every call.
315
328
  - **Do NOT guess command names — verb-noun composites are required.** The CLI uses explicit verb-noun forms; bare verbs do not exist. Confirm with `uip tm <resource> --help --output json`.
329
+ - **Do NOT `link-automation` Playwright test cases.** Playwright ingestion links them to the package automatically; the manual link step belongs to the Studio/RPA pipeline only.
@@ -0,0 +1,208 @@
1
+ # Playwright First Mile — Pack, Ingest, and Run on Serverless
2
+
3
+ End-to-end pipeline: take a Playwright test suite from a repo to executed results in UiPath Test Manager, using only `uip` commands. This flow is **Playwright-specific** — the pack command, the auto-created test cases, the `PW_*` labels, and the per-project run selection below do NOT apply to UiPath Studio/RPA packages. For Studio test automation use [publish-and-link-guide.md](publish-and-link-guide.md) instead; never mix the two pipelines.
4
+
5
+ ## Pipeline
6
+
7
+ ```
8
+ uip tm pack --type playwright → .nupkg with embedded test metadata
9
+ uip or packages upload → package on the Orchestrator feed
10
+ (Test Manager ingestion, automatic) → test cases auto-create, PW_* labels applied
11
+ uip tm testsets create → empty test set
12
+ uip tm testcases add --labels → fill it by label
13
+ uip tm testsets playwright-context → probe: is this a Playwright test set? which projects?
14
+ uip tm testsets run [--playwright-projects <names...>] → execute on serverless
15
+ uip tm wait / report / result → outcome
16
+ ```
17
+
18
+ The key difference from the RPA pipeline: there is **no link step**. Uploading the package is enough — ingestion creates one Test Manager test case per discovered Playwright test, already bound to the package, and labels each with:
19
+
20
+ - `PW_Tag_<tag>` — one per Playwright tag (`@smoke` → `PW_Tag_smoke`)
21
+ - `PW_Project_<name>` — one per Playwright project the test runs in
22
+ - `PW_Suite_<name>` / `PW_Path_<chain>` — describe-block grouping (name and full chain)
23
+ - `PW_File_<path>` — the spec file
24
+
25
+ > **Do NOT run `uip tm testcases link-automation` on Playwright test cases.** They are linked by ingestion; manual linking is the RPA pipeline and will corrupt the association.
26
+
27
+ > **Reading command output.** `--output json` prints a JSON envelope, but not on its own line: auto-updater chatter (including `Update completed with failures.`, which is unrelated to your command), `Resolved project …` progress lines and trailing telemetry warnings share the same stream. Judge a command by the `Result` field inside the envelope, never by surrounding text, and extract from the first `{` before parsing.
28
+
29
+ > **If a command is missing.** Two commands in this pipeline are hidden from `--help`, so `--help` is not a reliable way to tell whether a build has them: `testsets playwright-context` (Step 5) and `run --playwright-projects` (Step 6). Older CLIs answer `unknown command` / `unknown option` for them. Treat them differently:
30
+ >
31
+ > - **Probe missing** → skip Step 5 and continue. The probe only *reports* whether a test set is Playwright; it does not enable anything, so losing it costs you the pre-check, not the capability. Project scoping still works.
32
+ > - **`--playwright-projects` rejected** → this build cannot scope a run to selected projects. Run the test set without the flag (every project in the package's config runs) rather than retrying.
33
+
34
+ ## Prerequisites
35
+
36
+ - A Test Manager project to land the test cases in: `uip tm project list --filter <name> --output json`, or `uip tm project create --name <NAME> --project-key <PROJECT_KEY> --output json`. Capture the project key.
37
+ - The tenant's Test Manager must have Playwright support enabled (a server-side feature flag). If ingestion never produces test cases (Step 3), this is the first thing to suspect — stop and ask the user.
38
+ - The Playwright project directory must contain:
39
+ - `package.json` with `@playwright/test` installed (discovery shells out to the project's own `playwright test --list`; no browsers needed),
40
+ - a **lockfile** (`package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` / `bun.lock`) — serverless does a deterministic install,
41
+ - a `playwright.config` file.
42
+
43
+ ## Step 1 — Pack
44
+
45
+ ```bash
46
+ uip tm pack --project-path <dir> --type playwright \
47
+ --project-key <PROJECT_KEY> --name <PackageName> \
48
+ --package-version 1.0.0 -o <out-dir> --output json
49
+ ```
50
+
51
+ - `--project-key` is **required** by default because test-case auto-creation is on; pass `--no-create-test-cases` to pack without it (label metadata stays embedded for later use).
52
+ - Preview with `--dry-run` (writes nothing).
53
+ - Capture `Data.Output` (the `.nupkg` path) and `Data.TestCount` from the JSON output. `TestCount` is the number of test cases ingestion will create — remember it for Step 3.
54
+ - Pack fails loudly when the lockfile or `@playwright/test` is missing — fix the project, do not improvise around it.
55
+
56
+ ## Step 2 — Upload to Orchestrator
57
+
58
+ ```bash
59
+ uip or packages upload "<out-dir>/<PackageName>.1.0.0.nupkg" --output json
60
+ ```
61
+
62
+ `--package-version` is a NuGet/SemVer-style version: three numeric parts with an optional prerelease suffix (`1.0.0`, `1.0.1-beta.1`) — `1.0` is rejected. Each upload needs a version the feed does not already have, so before re-packing check what is published and go above it:
63
+
64
+ ```bash
65
+ uip or packages list --search <PackageName> --output json
66
+ ```
67
+
68
+ The match returns the feed's **latest** version only (one row, `IsLatestVersion: true`) — enough to pick the next version, but it is not a version history.
69
+
70
+ ## Step 3 — Wait for ingestion
71
+
72
+ Ingestion is asynchronous and automatic. Poll until the auto-created test cases appear:
73
+
74
+ ```bash
75
+ uip tm testcases list --project-key <PROJECT_KEY> --output json
76
+ ```
77
+
78
+ - Poll **unfiltered**. Do NOT pass `--filter <PackageName>` — `--filter` matches a test case's name or key by **prefix**, and an ingested test case is named `"<suite> > <test title>"`, so a package name never matches: the call stays empty forever and reads as a false "ingestion never happened".
79
+ - The rows carry `TestCaseKey` (e.g. `SHIP:1`) plus `Id` (the UUID) and `Name` — count `TestCaseKey`, not `Id`, when polling.
80
+ - Ingestion is done when `TestCount` new test cases from Step 1 are present, each named `"<suite> > <test title>"`. A plain `pack` prints only `Package`, `Output` and `TestCount` — if you want the exact expected names up front, run `--dry-run` first or read `testCases.json` inside the `.nupkg`; otherwise match on the count plus that name shape.
81
+ - `TestCount` from Step 1 is one test case per Playwright **test** — it is not multiplied by the number of Playwright projects (2 tests × 2 projects → 2 test cases).
82
+ - Ingested test cases show `IsAutomated: false` in list output; that is normal and does not mean ingestion failed.
83
+ - Poll every ~10 seconds for up to ~3 minutes. If the expected names never appear, STOP and report — the likely causes are the Playwright feature flag being off for the tenant or a wrong `--project-key`, and neither is fixed by retrying.
84
+ - Spot-check the labels landed: `uip tm objectlabel list --project-key <PROJECT_KEY> --object-type TestCase --filter PW_ --output json` (returns distinct label *names* only).
85
+
86
+ ## Step 4 — Set the default folder, create a test set, fill it by label
87
+
88
+ Set the project's default Orchestrator folder FIRST — both the Step 5 probe and the Step 6 run resolve packages through it (Critical Rule #10):
89
+
90
+ ```bash
91
+ uip or folders list --output json # WITHOUT --all: only folders you are a member of
92
+ uip tm project set-default-folder --project-key <PROJECT_KEY> --folder-key <FOLDER_KEY> --output json
93
+ ```
94
+
95
+ - Pick the folder from the **unflagged** `folders list` — `--all` returns every folder *visible* to you, including ones where you have no rights; choosing one of those fails later with `folderNotFoundOrNoAccess`.
96
+ The folder needs **two** things, and missing either one fails the run differently:
97
+
98
+ - **A Cloud Robots – Serverless machine** — without it job creation 500s and the execution is instantly `Cancelled`. Check with `uip or machines list --folder-key <FOLDER_KEY> --output json`; if none, create and assign one (one serverless machine per folder):
99
+
100
+ ```bash
101
+ uip or machines create -n <name> --serverless --testing-slots 2 --output json # capture Data.Key
102
+ uip or machines assign <MACHINE_KEY> --folder-key <FOLDER_KEY> --output json # takes machine KEYS (GUIDs), not names
103
+ ```
104
+
105
+ - **A folder member who can run unattended** — the run executes as a robot user drawn from the folder, and `uip tm testsets run` has no flag to choose one (only `uip tm testcases run` does), so folder membership is the only lever:
106
+
107
+ ```bash
108
+ uip or users list-in-folder --folder-key <FOLDER_KEY> --output json
109
+ uip or users get <USER_KEY> --all-fields --output json # needs MayHaveUnattendedSession: true
110
+ ```
111
+
112
+ Folder, machine and robot-user management is the platform skill's domain — see [/uipath:uipath-platform § orchestrator/setup-environment.md](../../uipath-platform/references/orchestrator/setup-environment.md) for the authoritative flags and the one-serverless-machine-per-folder rule. An ordinary interactive user usually has `MayHaveUnattendedSession: false`, and `uip or users update --allow-unattended` cannot fix that here — it requires a Windows unattended username and password, which serverless does not use. Assign an already-unattended-capable principal instead (a `DirectoryRobot` account is the reliable pick). Creating your own folder is a first-class option when no existing one qualifies: `uip or folders create <NAME> --output json` (name is positional), then attach a machine and such a user.
113
+
114
+ ```bash
115
+ uip tm testsets create --project-key <PROJECT_KEY> --name "PW Smoke" --output json
116
+ uip tm testcases add --test-set-key <TEST_SET_KEY> --labels "PW_File_<path>" --output json
117
+ ```
118
+
119
+ - Capture `TestSetKey` from the create output (e.g. `DEMO:10`).
120
+ - `--labels` is variadic and space-separated (quote names that contain spaces). Matching is **OR across labels, exact, and case-sensitive** — discover the real names first with `uip tm objectlabel list` rather than guessing.
121
+ - `--labels` works with any object label; the `PW_*` labels are simply what ingestion applies.
122
+ - Mutually exclusive with `--test-case-keys`; pass exactly one of the two.
123
+ - To run the whole suite on one browser: fill by a suite/file label (`PW_Suite_*` or `PW_File_*`) and pass the browser to `--playwright-projects` in Step 6. Filling by `PW_Project_<name>` is for selecting the subset of tests that participate in that project — it does not restrict which browsers run.
124
+ - **Labels select *tests*; `--playwright-projects` selects *browsers*.** Filling by `PW_Project_firefox` picks every test that runs in the firefox project (often all of them); it does not make the run firefox-only — that is what the run flag in Step 6 does. To "run only <project>", label-fill by whatever identifies the tests you want (tag, suite, file) and pass the project name to `--playwright-projects`.
125
+ - **Keep one test set = one Playwright package.** Per-project selection (Step 6) requires every test case in the set to come from a single Playwright package; label-filling across packages produces a set that cannot be project-scoped. Labels are NOT package-qualified — in a project holding several Playwright packages, a generic label like `PW_Tag_smoke` matches tests from all of them. There, fill by a package-unique label (`PW_File_<path>`, or a suite name unique to the package) or by explicit `--test-case-keys` from the current ingestion.
126
+
127
+ ## Step 5 — Probe the Playwright context (when available)
128
+
129
+ Before deciding whether `--playwright-projects` applies, ask the server:
130
+
131
+ ```bash
132
+ uip tm testsets playwright-context --test-set-key <TEST_SET_KEY> --output json
133
+ ```
134
+
135
+ Read the fields off the JSON response rather than relying on the names below staying current — this list describes today's shape, and `--output json` always carries whatever the API returns.
136
+
137
+ - `Data.IsPlaywright: true` → the set resolves to one Playwright package; `AvailablePlaywrightProjects` holds the only valid `--playwright-projects` values, and `SelectedPlaywrightProjects` shows any selection already stored on the test set. Both are **comma-joined strings** (`"chromium, firefox"`), not arrays — split on `", "` when scripting; no stored selection is `""`.
138
+ - `Data.IsPlaywright: false` → RPA, mixed, manual, or multi-package test set — run it **without** `--playwright-projects`.
139
+ - The server never errors on type here, so this is the safe discriminator for automation: probe first, branch on `IsPlaywright`.
140
+ - **False negative without a folder:** the probe resolves the package through the project's default folder — if that isn't set (Step 4), a genuine Playwright test set reports `IsPlaywright: false`. Set the default folder before trusting a `false`.
141
+
142
+ ## Step 6 — Run, optionally per Playwright project
143
+
144
+ ```bash
145
+ uip tm testsets run --test-set-key <TEST_SET_KEY> \
146
+ --playwright-projects chromium --output json
147
+ ```
148
+
149
+ `--playwright-projects` does not appear in `uip tm testsets run --help` — functional but unlisted, so treat this guide as its reference rather than concluding the build lacks it. Semantics (all enforced with clear errors, nothing silently ignored):
150
+
151
+ - Space-separated, case-sensitive names from the package's `playwright.config`. Passing several (`chromium firefox`) runs all of them, but results stay one log per test case — not per browser — so a per-browser breakdown is not available from Test Manager; scope to one project when you need attributable results. Unknown names **fail fast, before anything is persisted**, listing the available projects.
152
+ - Valid only when every test case in the set comes from one single Playwright package (see Step 4); fails for Studio/RPA test sets — run those without the flag.
153
+ - The selection **persists on the test set** and applies to later runs until changed; omit the flag to reuse the stored selection (or the config's defaults if none was ever stored).
154
+ - On a Test Manager without Playwright support the command fails with instructions rather than running incorrectly.
155
+
156
+ Omit `--playwright-projects` entirely for a plain run (all config-default projects).
157
+
158
+ **Getting the execution id.** Start the run **without** `--wait`: it returns a complete JSON envelope immediately, carrying `ExecutionId` and `Status: Pending` — the cleanest handle for automation. With `--wait` the envelope only arrives at terminal state, so take the id from the `Execution started: <id> (Pending)` progress line — not from `Starting execution for test set …`, whose UUID is the *test set*.
159
+
160
+ **Agent-friendly waiting:** a single `--wait` call can sit silent for many minutes, which trips agent-harness watchdogs and shell timeouts. When running as an agent, prefer starting the run **without** `--wait`, then poll in bounded chunks: `uip tm wait --execution-id <EXECUTION_ID> --timeout 120 --output json` in a loop (or `uip tm executions get-stats` every 30–60 s), so every call returns quickly and progress stays visible. `wait` polls on a fixed 60 s interval, so keep `--timeout` a multiple of that — a shorter timeout can report a timeout for a run that already finished. A `wait` that hits its `--timeout` returns a Failure envelope with `Retry: "RetryWillNotFix"` — for a non-terminal execution that just means "still running"; keep polling, don't treat it as fatal.
161
+
162
+ ## Step 7 — Results
163
+
164
+ - `--wait` on the run blocks until terminal; without it, use `uip tm wait --execution-id <EXECUTION_ID> --output json`.
165
+ - Summary: `uip tm report get --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json` (`--project-key` or `--test-set-key` is required — bare `--execution-id` exits with "Provide --project-key or --test-set-key").
166
+ - Per-test detail: `uip tm executions testcaselogs list --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json`. Judge pass/fail by `Result` (`Passed` / `Failed` / `None`) — a failed test still reports `HasError: false`, so that field is not the outcome.
167
+ - JUnit export: `uip tm result download --execution-id <EXECUTION_ID> --result-path <dir> --output json` — counts only for Playwright: the XML names every case after the spec file, not the test title, so use `testcaselogs list` when you need to know *which* test failed.
168
+ - **Proving the run was scoped as asked:** `uip tm executions get-stats --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json` returns a `PlaywrightExecutionSnapshot` whose `Projects` is the project list the run actually used (`["chromium"]`). Read only `Projects` from it — its `Version` is two-component (`1.0`), like `list-automations` and `playwright-context`, so none of the three can tell 1.0.1 from 1.0.0; `TestCaseVersion` on the logs is the only field that can. Counting logs proves nothing here — there is one test case log per Playwright **test**, not per test × project, so a two-project run yields the same number of logs as a one-project run.
169
+
170
+ Execution happens on UiPath serverless cloud runtimes — no robot or package deployment into the folder is needed beyond the upload in Step 2, but the folder does need its serverless machine assignment (Step 4).
171
+
172
+ ### When a run produces no results
173
+
174
+ Three shapes, one rule: diagnose with the two commands below, then stop — retrying doesn't fix any of them.
175
+
176
+ - **`Cancelled` within seconds**, logs pointing at `CreateTestAutomationJobs` / `InternalServerError` → the default folder has no serverless machine assigned (Step 4).
177
+ - **`Finished` with `Passed: 0 / Failed: 0 / None: N`** → the run ended without per-test results reaching Test Manager; the test case log's `Info` carries the reason (results upload failed, or the job never started). Note `report get` counts `None` as **`Skipped`**, so 0% here means "results lost", not "tests skipped".
178
+ - **Stuck `Pending`** → dispatch worked but nothing is executing. A faulted job may never sync back, so don't sit out the 30-minute wait; check after ~5 minutes. Fixing the folder does **not** rescue an already-pending execution — start a new run after fixing.
179
+ - **`Serverless.Runtime.CannotIssueUserTokenDueToUserNotPartOfOrg`** in a log's `Info` → the folder's robot-user pool is bad: the account Test Manager picked is still folder-assigned but no longer valid in the org. Unlike the shapes above this **is** fixable from the CLI — point the project at a folder whose members satisfy Step 4 (or create one), then re-run.
180
+
181
+ ```bash
182
+ uip tm executions testcaselogs list --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json
183
+ uip or jobs list --folder-key <FOLDER_KEY> --output json
184
+ ```
185
+
186
+ Everything past the Test Manager boundary — job states, machines, folder membership — belongs to [/uipath:uipath-platform § orchestrator/run-jobs.md](../../uipath-platform/references/orchestrator/run-jobs.md) and [§ orchestrator/setup-environment.md](../../uipath-platform/references/orchestrator/setup-environment.md); use those for the job-side detail. A `Duration` of `00:00:00` and an empty `StartTime` on an already-finished execution are normal — not evidence of a broken run. `JobKey` values on the logs prove Test Manager dispatched; jobs `Faulted` with no host machine mean the tenant can't run them. Either way it needs the platform team — report it rather than re-running (there is no CLI verb to cancel a Test Manager execution).
187
+
188
+ ## Iterating on the suite (and getting a fix back in)
189
+
190
+ Changing a test — including fixing one the run just failed — uses the same pipeline with a bumped version:
191
+
192
+ ```bash
193
+ uip tm pack --project-path <dir> --type playwright --project-key <PROJECT_KEY> --name <PackageName> --package-version 1.0.1 -o <out-dir> --output json
194
+ uip or packages upload "<out-dir>/<PackageName>.1.0.1.nupkg" --output json
195
+ ```
196
+
197
+ The version **must** be new — the Orchestrator feed rejects one it already has (Step 2). Ingestion then **updates** the existing test cases in place (matched per test), creates any new ones, and unlinks removed ones, so:
198
+
199
+ - **A test set keeps its membership** when the test list is unchanged — nothing to re-add, no new test set, re-run the same `--test-set-key`. Only re-run `uip tm testcases add --labels` if new tests should join.
200
+ - **A stored Playwright project selection survives** too, so the re-run stays scoped.
201
+
202
+ **Confirming the new package actually ran:** the test case logs carry `TestCaseVersion`, so after the re-run
203
+
204
+ ```bash
205
+ uip tm executions testcaselogs list --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json
206
+ ```
207
+
208
+ reports the version you just packed (`1.0.1`). That is the reliable check — `list-automations` shows a two-component `PackageVersion` (`1.0`) that cannot distinguish 1.0.1 from 1.0.0. Ingestion of an update is otherwise invisible (same count, same names), so allow ~60–90 s after the upload before re-running; an old `TestCaseVersion` in the results means a stale package, not a bad fix.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "skillsVersion": "1.199.0-preview.106",
3
+ "skillsVersion": "1.199.0-preview.218",
4
4
  "targetCli": "^1.199.0"
5
5
  }
@@ -1,168 +0,0 @@
1
- # IS-Activity Tool Authoring
2
-
3
- Wrap an Integration Service connector activity as an MCP tool via `uip agenthub mcp-tools create-is-activity`. Discovery verb is `uip is resources run` / `describe` (pre-rename `execute` → use `run`).
4
-
5
- **Division of labor.** The metadata-*discovery* workflow — `describe`, reference resolution, cascade (`-f`), scope filtering, static-value labeling — lives in the platform IS references below; this file does not restate it. This file owns the MCP-tool layer: turning discovered metadata into the `create-is-activity` payload (`ActivityMetadata`, `inputSchema`, `outputSchema`). **Do not author IS metadata from memory** — a `designTimeLookups` / `-f` / `reference` shape that "looks right from a rule" still gets the wrong shape per connector and fails at runtime after passing `--dry-run`. Read the platform section at the action-trigger below even when confident.
6
-
7
- ## Availability (rollout gate)
8
-
9
- IS-activity MCP tools are rolling out: live on alpha/staging; NOT yet on `cloud.uipath.com` (prod — server-side feature flag per tenant). CLI enforces this: `candidates --category is-activity` and `create-is-activity` fail fast with `Reason: IsActivityNotAvailable` on unavailable hosts. The gate follows the payload, not just the verb: `create-resource` / `create-raw` / `update` carrying an IS-activity payload (`type: 1` + `processType: "Api"`, via `--file`/`--body`) are gated identically — there is no smuggling route. On that error: STOP — do not retry, do not run `create-is-activity` to "confirm" the gate (the error already covers every is-activity verb), do not re-author the same payload through `create-raw` / `update`. Tell the user the feature is not yet available on this environment; offer `resource` / `raw` tools instead — meaning a genuinely different tool kind (Orchestrator resource binding / non-IS raw payload), NOT the IS-activity payload under another verb. Re-run with `--force` (accepted on every gated verb) ONLY when the user confirms the tenant is enrolled in the rollout. CLI versions without the gate: the create succeeds but yields a dead tool (hidden in UI, not invocable) — apply the same rule manually before authoring: base URL is `cloud.uipath.com` → stop and ask.
10
-
11
- ## Platform IS references — read by action
12
-
13
- In `../../uipath-platform/references/integration-service/`. Each is small. Do NOT read all upfront — before performing each action, read the named section first. The blind spots are unknown-unknowns, so the trigger is the action, not your sense of certainty.
14
-
15
- | Before this action | First read |
16
- |---|---|
17
- | `uip is connections list <key>` for the first time | `connections.md` §`Folder Scoping` (pass `--all-folders`) |
18
- | `is resources describe ... -f <parent>=<value>` (any cascade re-run) — **mandatory, incl. curated activities you "know" (Jira `curated_create_issue`)** | `resources.md` §`Parent-Field-Driven Custom Fields` (`-f` shape, `--operation` requirement, `--action` rule, merge semantics) |
19
- | A `staticValues.<bucket>.<field>` whose describe field has a `.reference` block | `reference-resolution.md` §`Static Reference-Value Labeling` (`designTimeLookups` format + cascade-scope edge cases) |
20
- | An `inputSchema.properties.<field>` whose `.reference.path` contains `{otherField}` | `reference-resolution.md` §`Field Dependency Chains` (resolve parent first) |
21
- | An `inputSchema.properties.<field>` whose `.reference.filterPattern` contains `{filter}` | `reference-resolution.md` §`Search References` |
22
- | Resolving a reference where `run list` returns `scope: null` AND `scope.type: "PROJECT"` rows | `reference-resolution.md` §`Scope Filtering` |
23
- | Diagnosing a `describe` server-side failure | `resources.md` §`Describe Failures` |
24
- | Final gate before `create-is-activity --dry-run` | `reference-resolution.md` §`Validate Required Fields Before Executing` |
25
-
26
- ## Critical rules (extend SKILL.md)
27
-
28
- 1. **Discover before authoring.** `candidates --category is-activity` resolves connector + activity; `is resources describe` pulls field metadata. Compose `metadata` / `inputSchema` / `outputSchema` from the describe response, never from memory — every connector + operation has its own shape.
29
- 2. **Enumerate connections across ALL folders, then pick.** Discovery: `uip is connections list <connector-key> --all-folders --output json` — one call spanning every folder you can see. Mandatory on EVERY connections listing — including verification when the user already named a connection or folder. Never call the bare form: without `--all-folders` the call silently scopes to the current context and may return empty; `--all-folders` is mutually exclusive with `--folder` / `--folder-key`. Capture each row's folder — the user picks connection + folder together (Pre-flight 1). Pass `--target-identifier <connection-guid>`; `targetFolderKey` then defaults to the MCP server folder. Connection in a different folder → set it explicitly with `--target-folder-path <name>` / `--target-folder-key <guid>` (mirrors `--folder-path` / `--folder-key`, never both); the cross-folder guard allows an explicit target folder. Neither target-folder flag passed and `Reason: CrossFolderConnection` → pick from `Data.candidates`. (`connections.md` §`Folder Scoping` / §`Selecting a Connection`)
30
- 3. **Cascade api-type ObjectActions.** Before the first `-f` cascade re-run you **MUST read `resources.md` §`Parent-Field-Driven Custom Fields`** — the pointers in this rule are a map, not a substitute. Knowing a connector's cascade fields from memory (e.g. Jira `curated_create_issue` = `project.key` + `issuetype.id`) does NOT exempt you: the `-f` shape, `--operation` requirement, `--action` rule, and merge semantics vary per connector and change over time; a shape that "looks right" passes `--dry-run` and fails at runtime. Then: `describe <key> <objectName> --connection-id <id> --operation <op>`; if `requestFields` is short for the operation, re-run with `-f <parent>=<value>` (repeatable). Omit `--action` for Jira `curated_create_issue` Create (passing it → `No api-type ObjectAction matched`); pass `--action` only when describe reports multiple matches. Cascade examples: Jira `curated_create_issue`, Salesforce `query_records`, Dataservice V3.
31
- 4. **Baked static reference values need `designTimeLookups`.** Every `staticValues.<bucket>.<field>` (any bucket — `field` / `query` / `header` / `path`) whose describe field has a `.reference` block MUST emit `designTimeMetadata.designTimeLookups[<dotted-field>] = "<displayName> - <value>"`. Applies to `requestFields[]` and `parameters[]`; NOT to runtime / enum fields — labeling renders only for baked values. (`reference-resolution.md` §`Static Reference-Value Labeling`)
32
- 5. **Stringify `metadata` / `inputSchema` / `outputSchema` as scalars** — SDK types them `string | null`. Build each in a file and pass `--metadata "$(jq -c . metadata.json)"`; do not assemble multi-KB JSON inline, and do not mix `--file` with scalar options (`ConflictingInput`). `--output-schema "{}"` when the activity has no `responseFields` (empty string → `Unexpected end of JSON input`).
33
- 6. **Ask — don't guess — when a value drives discovery.** Cascade `-f` parents, a search-reference `{filter}`, a dependency-chain parent, or a required reference with no user hint: STOP and ask, even in autonomous mode. **No autonomous fallback exists.** If the user defers ("Other" / "you decide" / silence), re-ask in plain text — do NOT fall back to free runtime, a guessed default, or silently skipping the tool. Bounded set (2–4 candidates) → `AskUserQuestion` (do not add "Other"; it is auto-appended; <2 options errors). Unbounded set (dozens+) → plain text showing the top 5–10 candidates by a real attribute plus the exact format you need (`"<project key> + <issue type>"`). Never filter an unbounded `run list` with a guessed `JMESPath` name — a miss returns `[]` with no signal.
34
-
35
- ## Reference fields — the 3-way choice
36
-
37
- For every `requestFields[name].reference` or `parameters[name].reference` (`reference-resolution.md` §`Reference Fields`), run `uip is resources run list <connector> <reference.objectName> --connection-id <id> --output json`, then pick per field:
38
-
39
- - **(a) Bake** — `staticValues.<bucket>.<field> = <value>` + a `designTimeLookups` entry (Rule 4). When one value applies to every call (user named it).
40
- - **(b) Constrained runtime** — `inputSchema.properties.<field> = {type: string, enum: [<discovered values>]}`. When the set is bounded (≤ 20–50), stable, known now. No lookup needed.
41
- - **(c) Free runtime** (default) — `inputSchema.properties.<field> = {type: string}`, no enum. When the set is large / volatile (IDs, free text, search inputs). The `description` is the prompt the consuming LLM reads: noun phrase + format (e.g. `"IANA timezone like 'UTC'"`) + omission behavior + constraints.
42
-
43
- Cascade roots and search references with no user-supplied filter = **hard ask** (Rule 6) — no "pick first" / "most-recent" default. Non-cascade required references default to (c) in autonomous mode; use (b) only when the set is genuinely small and stable.
44
-
45
- ## Pre-flight (walk before drafting `--metadata`)
46
-
47
- 0. **Scope.** Restate server slug, folder, exact tool list (one bullet per `<connector> · <activity> · <op>`), baked statics. Folder: if unnamed, `uip or folders list --output json` → `Shared` (org-default) or `<email>'s workspace` (personal needs `--folder-key <guid>`). Run `mcp-tools list --mcp <slug> --folder-path <name>` first — same name + connector + objectName exists → ask update vs add-new.
48
- 1. **Connection** — Rule 2: enumerate with `--all-folders` FIRST. Exploring every folder is mandatory before presenting any choice — never ask off a single-folder view. Then ask which connection + folder to use: present name / owner / folder per row, never UUIDs (`connections.md` §`Selecting a Connection`); 2–4 rows → `AskUserQuestion`, more → plain-text top list. Confirm even on a single match. A connection in ANY folder is usable (Rule 2's target-folder flags). Zero across all folders → surface a create-connection hint and STOP.
49
- 2. **Activity disambiguation.** `candidates --category is-activity --connector <key>` returns ≥2 overlapping entries (`send_message_to_channel` vs `_to_user`) → ASK. GET tie-break: `Get…` / `Find…` without an id → `List`; `Get … by …` or path `{id}`/`{key}` → `Retrieve`; unsure → describe without `--operation`, present `Data.availableOperations[]`.
50
- 3. **Reference fields** — the 3-way choice above, per field.
51
- 4. **Required scalar with no enum / reference / description** → STOP, ask (e.g. Slack `UsersByEmail.By`). Do not bake a guess.
52
-
53
- Multi-tool builds ("server with tools for X and Y"): re-walk Pre-flight + the command steps per tool — by tool 3 you drift toward tool 1's model.
54
-
55
- ## `ActivityMetadata` (the object to stringify into `--metadata`)
56
-
57
- ```jsonc
58
- {
59
- "connector": { "key": "<connector-key>" }, // from candidates
60
- "object": {
61
- "path": "<availableOperations[chosen].path — e.g. /issue/{issueKey}/comment/{commentId}>",
62
- "objectName": "<the describe argument, e.g. issue_comment>",
63
- "method": "<GET|POST|PATCH|PUT|DELETE — from availableOperations[chosen].method>",
64
- "contentType": "application/json"
65
- },
66
- "mapping": {
67
- "path": ["issueKey", "commentId"], // property names filling {placeholder} tokens in object.path
68
- "query": ["maxResults", "startAt"], // parameters[i] where .type === "query"
69
- "header": [], // parameters[i] where .type === "header"
70
- "field": [] // body fields (typically requestFields[])
71
- },
72
- "staticValues": {
73
- "query": { /* field-name: literal value the LLM cannot override */ },
74
- "header": { },
75
- "path": { },
76
- "field": { /* body fields the LLM cannot override */ }
77
- },
78
- "designTimeMetadata": {
79
- "designTimeLookups": {
80
- // one entry per staticValues.* field whose describe field has .reference
81
- // value format: "<displayName> - <baked-value>" e.g. "fields.project.key": "Orchestrator - OR"
82
- // see Critical Rule 4
83
- },
84
- "manageProperties": []
85
- },
86
- "metadataVersion": 1
87
- }
88
- ```
89
-
90
- `staticValues` holds only values the LLM cannot override (`processType`, baked enum choices, baked reference IDs); runtime values belong in `inputSchema.properties`. Emit flat dotted keys (`"fields.project.key": "OR"`); the FE may persist them nested on save — both round-trip through `ParameterMappingService`'s four-bucket iteration (`Query` / `Path` / `Header` / `Field`).
91
-
92
- `inputSchema.properties` = `requestFields ∪ parameters` not covered by `staticValues`. Per entry: name = `parameters[i].name` / `requestFields[j].name`; `title` = `displayName ?? name`; `description`; `type` from `dataType` / field shape; add to `required[]` when `.required === true`; honor `enum` / `.reference` (the 3-way choice). Curated activities often have empty `requestFields[]` before cascade — `parameters` is then the input source. Set `additionalProperties: false`. `mapping.path` must list every `{token}` in `object.path` by property name (CLI validates client-side).
93
-
94
- `outputSchema` is a real JSON Schema built from `Data.responseFields` (walk like `inputSchema.properties`). Do not ship `{"type":"object","additionalProperties":true}`. `"{}"` only when the activity genuinely has no response body.
95
-
96
- ## Workflow (commands)
97
-
98
- ```bash
99
- # 0 — folders (once per machine); personal workspace needs --folder-key, not --folder-path
100
- uip or folders list --output json
101
-
102
- # 1 — confirm / create the `uipath`-type server (slug ^[a-z0-9-]+$, len 3-50)
103
- uip agenthub mcp list --folder-path <folder> --output-filter "Data.items[].slug" --output json
104
- # server folder unknown → uip agenthub mcp list --all-folders --output json (then use its folder on every later call)
105
- uip agenthub mcp create uipath --name "<display>" --slug <slug> --folder-path <folder> --output json
106
-
107
- # 2 — connector key + activity (vendor name ≠ connector key; e.g. Slack → uipath-salesforce-slack)
108
- uip agenthub mcp-tools candidates --category is-activity --name <vendor> --output json
109
- uip agenthub mcp-tools candidates --category is-activity --connector <key> --output json
110
- # Read Data.items[].{connectorKey, objectName, methodName, displayName}. Multi-candidate → Pre-flight 2.
111
-
112
- # 3 — describe: operations, then field metadata (cascade/reference mechanics → platform refs)
113
- uip is resources describe <key> <objectName> --connection-id <id> --output json # Data.availableOperations[]
114
- uip is resources describe <key> <objectName> --connection-id <id> --operation <op> --output json
115
- # requestFields[] (body), parameters[] (path/query/header), responseFields[] (output).
116
- # Short requestFields → curated: cascade with -f. [READ FIRST, mandatory even if you know the fields: resources.md §Parent-Field-Driven Custom Fields]
117
-
118
- # 4 — connections across ALL folders (mandatory even when the user named the connection; folder may differ from server — step 7 --target-folder-*) [READ: connections.md §Selecting a Connection + §Folder Scoping]
119
- uip is connections list <connector-key> --all-folders --output json # never the bare form; present name/owner/folder; user picks connection + folder
120
-
121
- # 5 — label every baked static reference value [READ: reference-resolution.md §Static Reference-Value Labeling]
122
- uip is resources run list <connector> <reference.objectName> --connection-id <id> --output json
123
-
124
- # 6 — dry-run preview (skips some server-side checks; can pass while the real POST fails)
125
- uip agenthub mcp-tools create-is-activity ... --dry-run --output json # inspect Data.resolved.{metadata,inputSchema,outputSchema}
126
-
127
- # 7 — create
128
- uip agenthub mcp-tools create-is-activity \
129
- --mcp <slug> --name "<tool name>" --description "<1-4000 chars; shown in AgentHub UI>" \
130
- --folder-path "<server folder>" --target-identifier <connection-guid> \
131
- --target-folder-path "<connection folder; omit to default to server folder>" \
132
- --metadata "$(jq -c . metadata.json)" --input-schema "$(jq -c . input-schema.json)" \
133
- --output-schema "$(jq -c . output-schema.json)" --output json # Data.id = created tool ID
134
-
135
- # 8 — verify (do NOT claim done before this passes)
136
- uip agenthub mcp-tools list --mcp <slug> --folder-path <folder> --output json
137
- # Confirm id/name/description/mcpName. High-value tools: smoke-test via `uip is resources run <verb>`.
138
- ```
139
-
140
- Connection in a different folder than the server → add `--target-folder-path <name>` (or `--target-folder-key <guid>`, never both); resolves to `targetFolderKey`. Omit both → defaults to the server folder.
141
-
142
- Update (metadata/schemas changed) — scalars only, `--output-schema "{}"` for no response body:
143
-
144
- ```bash
145
- uip agenthub mcp-tools update <tool-id> --mcp <slug> --folder-path "<folder>" \
146
- --metadata "$(jq -c . metadata.json)" --input-schema "$(jq -c . input-schema.json)" \
147
- --output-schema "$(jq -c . output-schema.json)" --output json
148
- ```
149
-
150
- Delete: `uip agenthub mcp-tools delete <tool-id> --mcp <slug> --folder-key <guid> --output json`.
151
- Skeleton for `--file`: `uip agenthub mcp-tools template is-activity --output json`.
152
-
153
- ## IS-Activity Troubleshooting
154
-
155
- - **`Reason: IsActivityNotAvailable`** — environment not in the is-activity rollout (see §Availability). Gate follows the payload: also fires on `create-resource` / `create-raw` / `update` carrying an IS-activity payload. Stop; offer `resource` / `raw` (a genuinely different kind, not the same payload re-verbed); `--force` only for rollout-enrolled tenants.
156
- - **HTTP 400, no detail** — re-run `--dry-run`; CLI surfaces ASP.NET ProblemDetails as an `Errors` field of per-field failures.
157
- - **404 at runtime** — `metadata.mapping.path` missing a `{token}` from `object.path`. List every placeholder and retry.
158
- - **`Reason: CrossFolderConnection`** — connection in a different folder than the server. Pass `--target-folder-path <name>` / `--target-folder-key <guid>` for the connection's folder (guard allows an explicit target folder), or pick a `Data.candidates` entry via `--target-identifier <guid>`, or move the connection / server.
159
- - **`Operation 'X' not found. Available: <Y>`** — curated activity exposes only `Y`. Re-run `describe` without `--operation`, pick from `Data.availableOperations[]`.
160
- - **`No api-type ObjectAction matched for fields [...]`** — `-f` set matches no registered action, or `--action` was passed when it should be omitted (Jira `curated_create_issue` Create). Drop `--action` first; else inspect `connectorMethodInfo.design.actions[]` / `objectActions[]` for required `-f` shapes.
161
- - **Form renders raw scalar (`OR`, `3`) instead of a labeled value** — `designTimeLookups[<field>]` missing (Rule 4 / Step 5), then `mcp-tools update <tool-id>`.
162
- - **`ConflictingInput: Use exactly one of --file, --body, or scalar options.`** — pass schemas as scalars, not `--file`.
163
- - **`Unexpected end of JSON input` on `--output-schema`** — pass `"{}"` for no-response-body activities.
164
- - **`connections list <key>` empty / misses a known connection** — `--all-folders` missing; without it the call silently scopes to the current context. Re-run with `--all-folders` (mutually exclusive with `--folder` / `--folder-key`). Cross-folder is allowed — reference it via `--target-folder-path` / `--target-folder-key` (Rule 2); do NOT move the connection to the server folder. (`connections.md` §`Folder Scoping`)
165
- - **`Reason: TargetFolderMismatch` / `AmbiguousConnection`** — `--target-name` + explicit `--target-folder-*`: zero / multiple connections for the connector in the requested folder. Pick from `Data.candidates`, re-run with `--target-identifier <conn-guid>`.
166
- - **403 Forbidden at runtime** — connection scope mismatch; re-authorize via `uip is connections edit <id>` with broader scopes (`connections.md` §`Scope-Related Errors`).
167
-
168
- For generic AgentHub-MCP issues (slug regex, folder context, refresh-tools async/sync, `mcp delete` lookup), see SKILL.md §Troubleshooting.