TaskSultan Docs tasksultan.com

Migrating from UiPath

Checking a UiPath project can convert

The feasibility command, its per-activity verdicts, the second target axis and the exit codes.

uipath evaluate answers whether a workflow can be converted, one unit at a time and converts nothing. It never spawns a Robot, never writes a package and never touches a protected path. A half-migration whose failure surfaces at run time is the expensive failure this command exists to prevent, so the refusal comes first and by name.

#What it reads

A unit is a Studio project folder (project.json plus *.xaml), a published package (a content/ directory and a .nuspec), or a single .xaml file. From project.json it reads the name, projectVersion, the declared expressionLanguage and the declared package dependencies. It resolves the project's Object Repository under .objects/ so a target that exists only as a reference is resolved rather than dropped.

With --all the command walks a tree and reports every unit it finds: each project.json directory, each published package.

npx tsx orchestrator/cli.ts uipath evaluate ./MyProject
npx tsx orchestrator/cli.ts uipath evaluate ./estate --all --json

#The verdicts

Each authored activity gets one verdict. A file's XAML infrastructure (variables, arguments, property elements) is counted separately and never enters the coverage denominator.

Verdict Meaning
DIRECT The platform does this today through an existing surface.
COMPOSITE The action maps, but a neighbouring artefact must be re-authored (UI targets, nested workflows, table extraction).
MISSING No engine exists for it.
REFUSE It blocks an unattended run, so the platform declines to port it.
UNCLASSIFIED No rule matched the name. This blocks, exactly as MISSING does.
METADATA An element that belongs to another activity. Reported in its own bucket and excluded from the total.

The three blocking verdicts are MISSING, REFUSE and UNCLASSIFIED. Control flow (an If, a ForEach, an assignment) is counted as controlFlow and excluded from coverage, because nobody needs to ask whether TypeScript has an if.

The command reports a second axis beside the activity verdict. A unit's targetVerdict says whether its stored element targets can be addressed:

  • NO_TARGETS: the unit carries no element target.
  • READY: every target synthesised, nothing needs a human.
  • PARTIAL: some targets synthesised, some refused.
  • NEEDS_WORK: no target synthesised.

#Exit codes

The exit code is the verdict, so a caller classifies without parsing the report.

  • 0: every unit walked is CONVERTIBLE.
  • 1: at least one unit is BLOCKED.
  • 2: the pass could not produce an honest answer, because a file could not be read or the invocation itself was unreadable (an unknown option, an option handed another option as its value, or no path at all).

A file that cannot be read or parsed makes its unit ERROR and the run exit 2. An unreadable file is never absorbed into "0 activities, clean".

#Reading the report

unit        project "ACME_WI5"  ./MyProject
verdict     BLOCKED
coverage    DIRECT 41 (71.9%)  COMPOSITE 12 (21.1%)  MISSING 3  REFUSE 1  UNCLASSIFIED 0  [metadata 9 excluded]
files       6 workflow(s), 4 clean
selectors   web 5  desktop 1
targets     24 stored · synthesisable 5 · needs review 3 · refused 11 · window 4 · desktop 1  →  PARTIAL
blockers    4 (ranked):
      3  AttachWindow        MISSING      an automation drives a browser; there is no desktop-UI engine

The JSON form is the contract. The text form is what an operator reads and it ranks blockers by occurrence so the largest gap appears first. Each blocker carries the rule's own note, so a disputed verdict is argued with an entry rather than with authority.

#Things that catch people out

  • --all discovers units and returns each one; without it a directory is treated as one unit.
  • The declared expressionLanguage and the package dependencies are read from the manifest and reported, but they are not translated by this command.
  • The second axis is computed independently of the first. A unit can be CONVERTIBLE on activities and NEEDS_WORK on targets and both statements are true.
  • Nothing here executes any part of the workflow. The evaluation is a read.