Skip to content
Merged
2 changes: 1 addition & 1 deletion skills/uipath-rpa/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ On Windows PowerShell, `&` doesn't background — use `Start-Process powershell.
7. **[UIA] Before writing ANY UIA activity (XAML `<uix:N*>` or coded `uiAutomation.*` / `Descriptors.*`), MUST read [references/uia-starter-guide.md](references/uia-starter-guide.md) — via a two-step read, never a plain full Read: (1) Grep `^## Conditional Policies` on it, (2) Read with `limit` set to that line; the two policy sections below the marker load only when their stated condition applies.** Then the UIA package's core guide it mandates (`{PROJECT_DIR}/.local/docs/packages/UiPath.UIAutomation.Activities/ui-automation-guide.md`) IN FULL, and — before authoring — your mode's authoring guide IN FULL (routed from the core guide's § Documentation). No exceptions for "simple" UIs. Skipping this rule is the most common cause of hallucinated selectors, wrong target XML, and missing OR descriptors. NEVER hand-write selectors — use `uia-configure-target` exclusively (the package guide explains how). The package guide exists only after the package is installed — verify [uia-starter-guide.md § UIA Prerequisites](references/uia-starter-guide.md) first (Rule 7a); if the package is installed but the guide file is absent, the installed version predates it — treat as below the minimum version. The starter guide owns the skill-side UIA policies: run/debug procedure + runtime selector recovery, the stub-mode deliverable pattern, and UI Library publishing.
7a. **[UIA] Verify UIA prerequisites before invoking `uia-configure-target`.** The minimum version and the prerequisite check live in [uia-starter-guide.md § UIA Prerequisites](references/uia-starter-guide.md) — run that check first (do not hardcode the version from memory; that section is the only source of truth). If `UiPath.UIAutomation.Activities` is below the minimum or `{PROJECT_DIR}/.local/docs/packages/UiPath.UIAutomation.Activities/ui-automation-guide.md` is absent (Rule 7 treats a missing guide as below-minimum), the `uip rpa uia` CLI is unavailable — and **both** target capture and indication depend on it, so indication is *not* a fallback when the package itself is missing. Ask the user to install/upgrade per that section. If they decline or the package cannot be installed, fall back to the **Placeholder-Selector Stub Pattern** (§ above) — real activities with `TODO Indicate` markers need no CLI. Never silently route to a non-existent skill path. Use indication capture only when a compatible UIA package *is* installed but `uia-configure-target` cannot see the element; record `UI capture: indication-only` in the plan header to skip `uia-configure-target` in that case. **Runtime failure counts too:** when the package is present but the UIA snapshot CLI's live scans fail persistently (driver/COM errors on every scan), first rule out a locked or non-interactive Windows session (`LogonUI` running = lock screen) — that needs an unlock, not a fallback. Only if scans still fail on an unlocked interactive session, treat capture as unavailable and use the Placeholder-Selector Stub Pattern.
8. **Use `--output json`** on all CLI commands whose output is parsed programmatically.
8a. **A `run` / `debug start` verdict comes from `Data.errors` AND `Data.output` together — NEVER from the outer `Result`, and NEVER from any log entry's `level`.** A completed run passed only when `Data.errors` is empty **and** `Data.output` is `"Session ended"`. The outer `Result` qualifies the CLI invocation, not the workflow: it stays `"Success"` through unhandled exceptions, compile failures, and a missing entry point, so reading it as a verdict reports broken workflows as green. Both `Data` conditions are required, because `errors` stays empty for a missing entry point and for a debug session suspended on an exception, which report the failure in `output` instead. A successful workflow may emit `Log Message` activities at `Error` or `Warning` level as observability — those are workflow-emitted data, not failures, and treating log-entry levels as a failure signal flips green runs to "failed" and burns retries on healthy workflows. Once a run has failed, `logEntries` at `Error` level carry the most specific root cause. **Capture the verdict with `--output-filter` on the run command; never `| tail` the raw payload — `output` and `errors` precede the hundreds of `logEntries` lines, so tailing drops exactly the two fields this rule adjudicates on.** Copy-paste filter: [cli-reference.md § Capturing the verdict](references/cli-reference.md#capturing-the-verdict). See also [cli-reference.md § Reading run / debug results](references/cli-reference.md#reading-run--debug-results) and [debugging.md § Output Format](references/debugging.md#output-format).
8a. **A `run` / `debug start` verdict comes from `Data` — NEVER from the outer `Result` alone, and NEVER from a log line's level — and `Data`'s shape depends on the backend that ran the workflow; identify it by its keys.** Headless Studio (Helm — no Studio Desktop instance has the project open): `Data` is `{output, hasErrors, errorMessage, profiling, debugState, debugDetails}`; passed only when `hasErrors` is `false`, `errorMessage` is `null`, and `debugState` is `null` or `"Completed"`; a faulted `run` returns outer `Result: "Failure"` with those fields JSON-encoded in `Message`; a faulted `debug start` returns `Result: "Success"` with `debugState: "Suspended"` and the exception in `debugDetails` — the session is still alive and must be cancelled or continued. Studio Desktop (the project is open in a running Studio): `Data` is `{output, errors, logEntries, debugState}`; passed only when `errors` is empty AND `output` is `"Session ended"` — a missing entry point returns `Result: "Success"` with `errors: []` and `output: "Failed to open the file <path>"`, so both conditions are needed. Reading `Result: "Success"` as a verdict reports broken workflows as green on both backends. A successful workflow may emit `Log Message` activities at `Error` or `Warning` level as observability — on Helm they stream as `[Level]` lines above the envelope, on Desktop they are `logEntries` entries — and they are workflow-emitted data, not failures; treating them as a failure signal flips green runs to "failed" and burns retries on healthy workflows. **Read the verdict from the envelope as printed: no `--output-filter` on `run` / `debug start` (the two backends have different keys, and a filter naming a key the current backend lacks fails the call after the workflow has already run), and never `| tail` / `| head` the payload — on Helm the log lines precede the envelope, on Desktop the verdict fields precede a long `logEntries`, so either cut drops something this rule needs** ([cli-reference.md § Capturing the verdict](references/cli-reference.md#capturing-the-verdict)). Field meanings: [cli-reference.md § Reading run / debug results](references/cli-reference.md#reading-run--debug-results) and [debugging.md § Output Format](references/debugging.md#output-format).
9. **For "leverage / reuse / find shared libraries" requests, search the tenant feed — not the local filesystem, NuGet.org, or keyword-permutation loops.** Run `uip or libraries list --limit 500 --output-filter "<JMESPath>" --output json`. On zero results from the filtered call, take the fallback branch — do not re-keyword. Skip when an SDD already records §16 "Shared libraries referenced" or the user has said "no shared libraries" earlier in the session. See [tenant-library-search-guide.md](references/tenant-library-search-guide.md) for the full procedure.
10. **Register every test case file in `project.json` → `designOptions.fileInfoCollection`.** Applies to both XAML and coded test cases. Required keys, GUID format, JSON snippet, and full schema (including `dataVariationFilePath` for data-driven and `publishAsTestCase` for coded): [references/testing-guide.md § project.json Registration](references/testing-guide.md) and [assets/json-template.md](assets/json-template.md).

Expand Down
49 changes: 36 additions & 13 deletions skills/uipath-rpa/references/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
`uip rpa` connects to one of two Studio flavors behind the same IPC contract:

- **Headless Studio (Helm) — default.** Ships as a NuGet package and auto-launches on first use. **No Studio Desktop install needed.** First call on a cold NuGet cache may sit near-silent for 30–90 s while `dotnet restore` runs — the default shell timeout covers this; raise `timeoutSeconds` only behind a slow feed.
- **Studio Desktop.** The interactive UI. Used automatically only by verbs with **UI side effects** — those that open a window or highlight something in the designer (discover them via `--help`; they don't work headless). For such a verb, ensure Desktop is up first (`uip rpa studio start --project-dir "<PROJECT_DIR>"`), then run it. Force Desktop for any command with `UIPATH_RPA_TOOL_USE_STUDIO=1` (not recommended for the standard authoring loop).
- **Studio Desktop.** The interactive UI. A running Studio Desktop instance that has the project open handles that project's `uip rpa` calls — `run` and `debug start` included — and `uip rpa instances list --output json` shows which instance holds which project. Verbs with **UI side effects** (open a window, highlight something in the designer; discover them via `--help`) work only here: ensure Desktop is up first (`uip rpa studio start --project-dir "<PROJECT_DIR>"`), then run them. Force Desktop for any command with `UIPATH_RPA_TOOL_USE_STUDIO=1` (not recommended for the standard authoring loop). **The two backends return different `run` / `debug start` payloads** — see [Reading run / debug results](#reading-run--debug-results).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How would the model know it has a running SD instance? It would probably query the processes list, right?

Also, I fear the UIPATH_RPA_TOOL_USE_STUDIO=1 part is outdated. cc @DragosUnguru @RaduAna-Maria

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I ran additional tests with this branch rebased on latest main. The agent never writes about these details, it just runs the command and never comments about the output type, just observes the workflow succeeded.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It does feel more confident about its output interpretation:

Run passed: hasErrors: false, debugState: "Completed", and the log line reads Calculator result: 5 + 5 = 10.


`--studio-dir` is consulted **only when Studio Desktop is in use**; headless ignores it. When Desktop auto-detection fails, resolution falls back to `UIPATH_STUDIO_DIR`, then the default install path, then a dev build output. Errors like `"does not have interop support"` / `"Requires Studio 26.2+"` mean the detected Desktop is too old — tell the user to update it; this affects only the Desktop-only verbs.

Expand All @@ -93,33 +93,56 @@

`uip rpa run` runs a workflow with no debugging; the `debug` group drives breakpoints, stepping, and exception handling (see [debugging.md](debugging.md)). For UI automation, prefer `debug start` over `run` so the app is preserved for selector repair on error. Cancel an active run or session with `uip rpa execution cancel`. Pass workflow inputs as repeatable `--input-arguments key=value` pairs (see [Passing structured inputs](#passing-structured-inputs)); discover the remaining flags (log level, skip-build, profiling) via `--help`.

Both wrap the result in `{Result, Code, Data}`. **`Data`'s inner shape varies by CLI build and run state — read it by key presence, never by assumed schema.** A completed run returns the fields flat (`output`, `errors`, `logEntries` — the workflow's own `Log Message` output arrives in `logEntries`); suspended and stepping debug sessions, and older builds, nest a JSON-encoded string on `Data.runResult` (`HasErrors`, `ErrorMessage`, `DebugState`, `DebugDetails`, `Profiling`). Field-by-field meaning for both shapes: [debugging.md § Output Format](debugging.md#output-format).
Both wrap the result in `{Result, Code, Data}`. **`Data`'s shape is set by the backend that ran the workflow** ([§ Headless Studio (Helm) vs Studio Desktop](#headless-studio-helm-vs-studio-desktop)) — identify it by the keys present:

> **A completed run passed only when `Data.errors` is empty AND `Data.output` is `"Session ended"`.** The outer `Result` qualifies the CLI invocation, not the workflow — it stays `Success` through unhandled exceptions, compile failures, and a missing entry point, so **never read `Result: "Success"` as a passing run**. Both conditions are required, because `errors` stays empty for a missing entry point and for a debug session suspended on an exception. **DO NOT infer failure from a log entry's `level`** — a clean run that logs at `Error` still returns `errors: []` and `output: "Session ended"`; treating log levels as a verdict flips green runs to "failed" and burns retries. Field-by-field behavior per scenario: [debugging.md § Output Format](debugging.md#output-format).
| Backend | `Data` keys | Where the workflow's `Log Message` output is |
|---|---|---|
| **Headless Studio (Helm)** — no Studio Desktop instance has the project open | `output` (serialized output arguments, `"{}"` when none), `hasErrors`, `errorMessage`, `profiling`, `debugState`, `debugDetails` | streamed to stdout as `[<Level>] …` lines (`[Information]`, `[Error]`, …) **above** the JSON envelope; nothing inside `Data` |
| **Studio Desktop** — the project is open in a running Studio Desktop | `output` (status string: `"Session ended"` on completion), `errors` (array), `logEntries` (array of `{source, level, message}`, `source` = `Compile` or `Debug`), `debugState` (`"Completed"` on completion; absent when the file could not be opened) | inside `Data.logEntries`; nothing streams above the envelope |

Field-by-field meaning for both: [debugging.md § Output Format](debugging.md#output-format).

> **Verdict, Helm shape: passed only when `hasErrors` is `false` AND `errorMessage` is `null` AND `debugState` is `null` or `"Completed"`.** A `run` that faulted, failed validation, or named a missing entry point returns outer `Result: "Failure"` with the same field set JSON-encoded in `Message` (`hasErrors: true`, `errorMessage` = the failure text). A faulted `debug start` returns `Result: "Success"` with `hasErrors: false`, `debugState: "Suspended"`, the exception in `debugDetails` and command guidance in `errorMessage` — the session is still alive; cancel or continue it.
>
> **Verdict, Studio Desktop shape: passed only when `errors` is empty AND `output` is `"Session ended"`.** Both are required: a missing entry point returns outer `Result: "Success"` with `errors: []`, `logEntries: []` and `output: "Failed to open the file <absolute path>"`. An `--input-arguments` key the workflow does not declare is accepted silently (`"Session ended"`).
>
> **On either backend: never read the outer `Result: "Success"` as a passing run, and never infer failure from a `Warning` / `Error` log level** — `Log Message` activities emit at any level, and treating log levels as a verdict flips green runs to "failed" and burns retries.

### Capturing the verdict

**Always pass `--output-filter` on `run` / `debug start`.** It applies a JMESPath expression to `Data` server-side, so one call returns the verdict and the workflow's own `Log Message` output in ~14 lines:
**Run `run` / `debug start` with no `--output-filter` and read the envelope as printed.** The two backends return different key sets, so a filter written for one names keys the other does not have; the CLI then rejects the whole call with `Filter '…' failed to evaluate: Invalid type … received type null` *after* the workflow has already run (`length(errors)` on Helm, any function on `hasErrors` on Desktop), and the retry re-drives the application and costs a turn. On Helm the filter cannot reach the log lines at all — they are outside `Data`.

```bash
uip rpa debug start --file-path "<FILE>" --project-dir "<PROJECT_DIR>" --output json \
--output-filter "{output: output, errorCount: length(errors), errors: errors, runtimeLog: logEntries[?source=='Debug' && level!='Trace'].message | [-8:]}"
uip rpa run --file-path "<FILE>" --project-dir "<PROJECT_DIR>" --skip-build --output json
```

```json
Helm:

```text
[Information] Starting execution...
[Information] <PROJECT_NAME> execution started
[Information] Sum: 10
[Information] <PROJECT_NAME> execution ended in: 00:00:00
{ "Result": "Success", "Code": "ToolResult", "Data": {
"output": "Session ended", "errorCount": 0, "errors": [],
"runtimeLog": ["... execution started", "5 + 5 = 10", "... execution ended in: 00:00:08"] } }
"output": "{}", "hasErrors": false, "errorMessage": null, "profiling": null, "debugState": null, "debugDetails": null } }
```

Adjudicate straight off `output` and `errorCount` per the rule above; `runtimeLog` carries the workflow's own messages. The `source=='Debug'` term drops compile-phase noise (`Compiling files`, `Registering activities metadata`, dozens of `Unregistered service requested`); widen the slice past `[-8:]` for a chattier workflow.
Studio Desktop (same command, project open in Studio):

**Never `| tail -N` (or `| head`) the unfiltered payload.** `logEntries` runs to hundreds of trace lines, so tailing is the reflex — but `output` and `errors` are emitted *above* it, so tailing keeps the noise and drops the verdict. Recovering them means re-running, which re-drives the application; a workflow that is not re-run-safe behaves differently the second time.
```json
{ "Result": "Success", "Code": "ToolResult", "Data": {
"output": "Session ended", "errors": [],
"logEntries": [ { "source": "Debug", "level": "Information", "message": "<PROJECT_NAME> execution started" },
{ "source": "Debug", "level": "Information", "message": "Sum: 10" },
{ "source": "Debug", "level": "Information", "message": "<PROJECT_NAME> execution ended in: 00:00:06" } ],
"debugState": "Completed" } }
```

When a failure needs more than the filter shows (compile-phase error, root cause older than the slice), redirect the full payload — `> run.json` — and query the file. `jq` is absent on a standard Windows agent host; use PowerShell: `(Get-Content run.json -Raw | ConvertFrom-Json).Data.logEntries | Where-Object level -ne Trace`.
Adjudicate per the two rules above. The workflow's logged values are the `[Information]` lines above the envelope on Helm — read them there and do not strip them (`grep -v '^\['`) — and the `logEntries` entries on Desktop, where `Trace`-level entries (`Unregistered service requested …`, `Audit: …`) outnumber the workflow's own lines. On `debug start` through Helm, `debugState` / `debugDetails` carry the suspended-state exception that selector recovery needs.

> **A style diagnostic can fail the verdict.** `Data.errors` carries analyzer/IDE diagnostics, not just runtime faults — `IDE0063` ("'using' statement can be simplified") sets `output` to `"Execution aborted. See attached errors for more information"` though the body ran and logged normally. When `errors` holds a diagnostic ID rather than an exception, fix the code style and re-run; do not hunt for a runtime failure that did not happen.
**Never `| tail -N` or `| head -N` the payload.** On Helm the log lines precede the envelope, so either cut drops one of the two things you need; on Desktop `output` and `errors` precede a long `logEntries`, so `tail` drops the verdict. Recovering either means re-running, which re-drives the application; a workflow that is not re-run-safe behaves differently the second time. On a Helm `Result: "Failure"` envelope there is no `Data`: read `Message` — the `Data` fields JSON-encoded (`hasErrors: true`) for a `run` that faulted, failed validation, or named a missing entry point; `{"success": false, "errorMessage": "…"}` for a project directory that cannot be opened or an executor that is still busy.

When a failure needs more than the envelope shows (compile-phase error, a stack older than the visible lines), redirect the whole stdout — `> run.log` — and read it from the file: on Helm the `[Error]` lines plus the envelope's `errorMessage`, on Desktop the `errors` and `logEntries` arrays. `jq` is absent on a standard Windows agent host; the envelope is the last JSON object in the file.
---

## Passing structured inputs
Expand Down Expand Up @@ -183,7 +206,7 @@

Read the project's UI **Object Repository** — the saved hierarchy of applications, screens, and elements (selectors/targets) that UI Automation activities bind to. Two read commands cover the project's own entries and those exposed by referenced libraries; both require an open project.

> **Both verbs are top-level and hyphenated.** There is no `uip rpa object-repository` group — it returns `Unknown command: object-repository`, Studio running or not. Distinct from the UIA OR CLI, which writes entries and has no `get`.

Check warning on line 209 in skills/uipath-rpa/references/cli-reference.md

View workflow job for this annotation

GitHub Actions / skills/uipath-rpa

Possibly stale `uip rpa object-repository` (valid prefix: `rpa`)

- **Project Object Repository** — `uip rpa get-object-repository` returns the project's *own* Object Repository as a JSON tree of applications → screens → elements, each entry carrying `name`, `description`, `type`, and `reference`. Entries inherited from referenced libraries are **excluded** (use the library command below for those). Takes no arguments beyond the standard `--project-dir`.

Expand Down Expand Up @@ -406,9 +429,9 @@

```bash
# Focus a specific activity by its IdRef (from the error output):
uip rpa focus-activity --activity-id "Assign_1"

Check warning on line 432 in skills/uipath-rpa/references/cli-reference.md

View workflow job for this annotation

GitHub Actions / skills/uipath-rpa

Possibly stale `uip rpa focus-activity` (valid prefix: `rpa`)
# Focus all activities sequentially (useful for walkthrough):
uip rpa focus-activity

Check warning on line 434 in skills/uipath-rpa/references/cli-reference.md

View workflow job for this annotation

GitHub Actions / skills/uipath-rpa

Possibly stale `uip rpa focus-activity` (valid prefix: `rpa`)
```

This is especially useful when:
Expand Down Expand Up @@ -470,7 +493,7 @@

Output JSON includes the package `Id` (the package name Orchestrator stores) and `Version`. Hold on to the `Id` — `uip tm testcases link-automation` takes it as `--package-name`; `uip or processes create` takes it as `--package-key` (with `--package-version` separately).

> **There is no `uip or packages publish` or `uip rpa publish`.** Agents that try those names get "unknown command". Pack writes a file; upload pushes that file. Two commands, two domains (`rpa`, `or`).

Check warning on line 496 in skills/uipath-rpa/references/cli-reference.md

View workflow job for this annotation

GitHub Actions / skills/uipath-rpa

Possibly stale `uip or packages publish` (valid prefix: `or packages`)

### Discovery cheatsheet

Expand Down Expand Up @@ -511,7 +534,7 @@
| `timeout`, `ETIMEDOUT` | Cold Helm NuGet restore (30–90 s) or long operation. | Raise both limits together: shell `timeoutSeconds` toward its documented max, and `uip rpa --timeout <timeoutSeconds − 30> <command>` — the shell timeout must exceed `--timeout` by ≥ 30 s or the shell kills the CLI before it can cancel cleanly. For `validate`, also try `--skip-validation`. |
| `not authenticated`, `401`, `403` | Auth required for cloud features. | `uip login`, then retry. |
| `package not found`, `version not available` | Wrong package ID or version. | Verify via `uip rpa activities find`; omit `version` to auto-resolve latest. |
| `project not found`, `no project open` | Wrong `--project-dir` or project not open. | Verify the path points at the `project.json` folder; if it persists, `uip rpa project open --project-dir "<PROJECT_DIR>"`. For Desktop-only verbs, check instances with the hidden `uip rpa instances list --output json` and run `uip rpa studio start` if none is up. |

Check warning on line 537 in skills/uipath-rpa/references/cli-reference.md

View workflow job for this annotation

GitHub Actions / skills/uipath-rpa

Possibly stale `uip rpa project open` (valid prefix: `rpa`)
| `not in the project folder` (in `validate`) | Absolute `--file-path` + separator mismatch. | Pass `--file-path` relative to the project root (see [validate](#validate)). |
| `Studio is busy`, `operation in progress` | Studio processing a prior request. | Wait a few seconds, retry. |
| Unrecognized error | Unknown | Re-run with `--verbose` for debug detail, then inform the user. |
Expand Down
Loading
Loading