copy for LLM as markdown (or .xaml or pseudocode or..)
Jump-to list
canvas-inspired, tree and .xaml view
Seems that I can reduce token use by a factor of 4 when a coding agent is interacting with a UiPath Studio project. copy-as for quick pasting ito Claude Code was the major motivation.
Visually I overcome the most annoying visual-coding paradigm by
right-aligned
text
no-wrap (overflow to the right side)
Super-fast! On startup I am caching and need to wait a few seconds. After that I can jump around and scroll quickly.
and then “Copy-as” for LLM I get the following clipboard entry.
Again-again: I am viewing Main.xaml – and get the recursive transcluded invoked workflows.
As about every of my projects nowadays has .cs files it even works with reading coded-workflows into the AST
<workflow-fragment>
<source file="Main.xaml" lines="612-740" />
<location>General Business Process › Initialization › Try initializing settings and applications › If first run, read local configuration file</location>
<author-notes>
- General Business Process: [Process title] [Process description] [Additional information (e.g., author, contact information and applications involved and required external setup)]
- Initialization: Read configuration file and initialize applications used in the process.
- If first run, read local configuration file: An uninitialized Config dictionary indicates that it is the first run of the process.
</author-notes>
<activity>
If first run, read local configuration file [If]
# An uninitialized Config dictionary indicates that it is the first run of the process.
Condition = Config is Nothing
Then: First run:
Log Message screen resolution [LogMessage]
Level = "Info"
Message = "The primary screen resolution is: "+Screen.PrimaryScreen.Bounds.Width.ToString+" x "+ Screen.PrimaryScreen.Bounds.Height.ToString
Invoke InitAllSettings workflow [InvokeWorkflowFile]
UnSafe = "False"
invoke Framework/InitAllSettings.xaml
in_ConfigFile : x:String -> Data\Config.xlsx
in_ConfigSheets : s:String[] -> {"Settings", "Constants"}
out_Config : scg:Dictionary(x:String, x:Object) <- Config
Workflow:
Initialize All Settings [Sequence]
# Initialize, populate and output a configuration Dictionary to be used throughout the project.
# Settings and constants are read from the local configuration file, and assets are fetched from Orchestrator.
# Asset values overwrite settings and constant values if they are defined with the same name.
Log Message (Initialize All Settings) [LogMessage]
Level = "Trace"
Message = "Initializing settings..."
Assing out_Config (initialization) [Assign]
To = out_Config
Value = New Dictionary(of String, Object)
For each configuration sheet [ForEach]
Values = in_ConfigSheets
Body:
Get local settings and constants [Sequence]
# Read settings and constants from the configuration file and add them to the Config dictionary.
var dt_SettingsAndConstants : sd:DataTable
Read range (Settings and Constants sheets) [ReadRange]
AddHeaders = "True"
DataTable = Dt_SettingsAndConstants
SheetName = Sheet
WorkbookPath = in_ConfigFile
For each configuration row [ForEachRow]
DataTable = Dt_SettingsAndConstants
Body:
If configuration row is not empty [If]
# Read non-empty rows in the sheet.
Condition = Not String.IsNullOrWhiteSpace(row("Name").ToString.Trim)
Then:
Add Config key/value pair [Assign]
To = out_Config(Row("Name").ToString.Trim)
Value = Row("Value")
Try initializing assets [TryCatch]
Try:
Get Orchestrator assets [Sequence]
# Get from Orchestrator the values of assets listed in the Assets sheet.
var dt_Assets : sd:DataTable
Read range (Assets sheet) [ReadRange]
AddHeaders = "True"
DataTable = dt_Assets
SheetName = "Assets"
WorkbookPath = in_ConfigFile
For each asset row [ForEachRow]
DataTable = dt_Assets
Body:
Try retrieving asset from Orchestrator [TryCatch]
Try:
Get asset from Orchestrator [Sequence]
var AssetValue : x:Object
Get Orchestrator asset [GetRobotAsset]
AssetName = row("Asset").ToString
CacheStrategy = "None"
FolderPath = row("OrchestratorAssetFolder").ToString
Value = AssetValue
Assign asset value in Config [Assign]
To = out_Config(row("Name").ToString)
Value = AssetValue
Catches:
Catch
Body [Sequence]
If asset name is specified, but it cannot be retrieved [If]
# Logs a message and throw exception in case the asset is specified in the Config file, but it could not be loaded from Orchestrator.
Condition = Not String.IsNullOrWhiteSpace(Row("Name").ToString.Trim)
Then:
Throw AssetFailedToLoad Exception [Throw]
Exception = new Exception("Loading asset " + Row("Asset").ToString + " failed: " + Exception.Message)
Catches:
Catch
Rethrow loading asset exception [Rethrow]
If in_OrchestratorQueueName is specified [If]
# Overwrite queue name from in configuration file in case the argument in_OrchestratorQueueName is specified.
# This provides backward compatibility with < 2018.3.
Condition = Not String.IsNullOrWhiteSpace(in_OrchestratorQueueName)
Then:
Assign OrchestratorQueueName [Assign]
To = Config("OrchestratorQueueName")
Value = in_OrchestratorQueueName
If in_OrchestratorQueueFolder is specified [If]
# Overwrite folder name from in configuration file in case the argument in_OrchestratorQueueFolder is specified.
# This provides backward compatibility with < 2018.3.
Condition = Not String.IsNullOrWhiteSpace(in_OrchestratorQueueFolder)
Then:
Assign OrchestratorQueueFolder [Assign]
To = Config("OrchestratorQueueFolder")
Value = in_OrchestratorQueueFolder
Invoke KillAllProcesses workflow (first run) [InvokeWorkflowFile]
# Kills all Windows processes representing applications used in this business process to assure that the execution starts in a clean state.
# Since the applications are assumed to be already closed, CloseAllApplications is skipped and just KillAllProcess is invoked.
UnSafe = "False"
invoke Framework/KillAllProcesses.xaml
Workflow:
Kill All Processes [Sequence]
# Use the Kill Process activity to force the termination of the Windows processes representing applications used in the business process being automated.
# Note that killing processes might have undesirable outcomes, such as losing unsaved changes to files.
Log message (Kill processes) [LogMessage]
Level = "Trace"
Message = "Killing processes..."
Add Log Fields (BusinessProcessName) [AddLogFields]
# Add the process name to the logs generated after this point.
# This log field can be used to create reports and visualizations about the process.
Fields = Config("logF_BusinessProcessName").ToString
</activity>
<variables-in-scope>
- Config : scg:Dictionary(x:String, x:Object) (declared in "General Business Process")
- dt_Assets : sd:DataTable (declared in "Get Orchestrator assets")
- AssetValue : x:Object (declared in "Get asset from Orchestrator")
</variables-in-scope>
<workflow-arguments-used>
- In in_OrchestratorQueueName : x:String
- In in_OrchestratorQueueFolder : x:String
</workflow-arguments-used>
<invoked-workflows>
- Framework/InitAllSettings.xaml
- Framework/KillAllProcesses.xaml
</invoked-workflows>
</workflow-fragment>