@minicor/mcp-server 3.1.5 → 3.2.0

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.
Files changed (54) hide show
  1. package/README.md +251 -61
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/laminar-client.d.ts +5 -0
  6. package/dist/laminar-client.d.ts.map +1 -1
  7. package/dist/laminar-client.js +6 -0
  8. package/dist/laminar-client.js.map +1 -1
  9. package/dist/lib.d.ts.map +1 -1
  10. package/dist/lib.js +2 -0
  11. package/dist/lib.js.map +1 -1
  12. package/dist/prompts/build-rpa.d.ts.map +1 -1
  13. package/dist/prompts/build-rpa.js +86 -272
  14. package/dist/prompts/build-rpa.js.map +1 -1
  15. package/dist/prompts/debug-execution.js +1 -1
  16. package/dist/seed-skills.d.ts +13 -0
  17. package/dist/seed-skills.d.ts.map +1 -0
  18. package/dist/seed-skills.js +82 -0
  19. package/dist/seed-skills.js.map +1 -0
  20. package/dist/skills-service-client.d.ts +54 -0
  21. package/dist/skills-service-client.d.ts.map +1 -0
  22. package/dist/skills-service-client.js +93 -0
  23. package/dist/skills-service-client.js.map +1 -0
  24. package/dist/skills.d.ts +34 -0
  25. package/dist/skills.d.ts.map +1 -0
  26. package/dist/skills.js +152 -0
  27. package/dist/skills.js.map +1 -0
  28. package/dist/sync.d.ts +18 -2
  29. package/dist/sync.d.ts.map +1 -1
  30. package/dist/sync.js +404 -104
  31. package/dist/sync.js.map +1 -1
  32. package/dist/tools/core.d.ts.map +1 -1
  33. package/dist/tools/core.js +12 -0
  34. package/dist/tools/core.js.map +1 -1
  35. package/dist/tools/skills.d.ts +3 -0
  36. package/dist/tools/skills.d.ts.map +1 -0
  37. package/dist/tools/skills.js +429 -0
  38. package/dist/tools/skills.js.map +1 -0
  39. package/dist/tools/sync-tools.d.ts.map +1 -1
  40. package/dist/tools/sync-tools.js +53 -12
  41. package/dist/tools/sync-tools.js.map +1 -1
  42. package/dist/tools/vm.js +1 -1
  43. package/dist/tools/workflow-ops.js +1 -1
  44. package/dist/tools/workflow-ops.js.map +1 -1
  45. package/package.json +4 -2
  46. package/skills/general/cdp-browser-automation.md +97 -0
  47. package/skills/general/data-extraction-strategies.md +64 -0
  48. package/skills/general/data-hydration-patterns.md +167 -0
  49. package/skills/general/data-passing-between-steps.md +46 -0
  50. package/skills/general/desktop-uiautomation.md +80 -0
  51. package/skills/general/rpa-testing-workflow.md +145 -0
  52. package/skills/general/session-keepalive.md +101 -0
  53. package/skills/general/smart-launch-patterns.md +213 -0
  54. package/skills/general/state-verification.md +56 -0
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: desktop-uiautomation
3
+ description: Desktop RPA patterns using uiautomation, pywinauto, and pyautogui. Framework selection by app type, element-based selectors over coordinates, wait-for-element patterns, retry strategies, popup dismissal. Use when building desktop automations or Windows app RPA.
4
+ category: general
5
+ tags: [desktop, uiautomation, pywinauto, pyautogui, windows, jab]
6
+ priority: 10
7
+ ---
8
+
9
+ # Desktop UI Automation
10
+
11
+ ## Framework Selection
12
+
13
+
14
+ | App Type | Framework |
15
+ | ---------------------------- | --------------------------------------- |
16
+ | .NET / WPF / WinForms | `uiautomation` (default) or `pywinauto` |
17
+ | Java / Swing | `jab` (Java Access Bridge) |
18
+ | Electron / web-based desktop | `pywinauto` or `pyautogui` |
19
+ | Legacy Win32 | `uiautomation` |
20
+ | Unknown | Start with `uiautomation` |
21
+
22
+
23
+ Desktop scripts use `/execute` and run **one at a time** per VM (the physical screen is shared).
24
+
25
+ ## Wait for Elements (Never `time.sleep` for UI Waits)
26
+
27
+ ```python
28
+ for _ in range(20):
29
+ el = auto.WindowControl(Name="Patient Search")
30
+ if el.Exists(0.5): break
31
+ time.sleep(0.5)
32
+ else:
33
+ raise TimeoutError("Patient Search not found after 10s")
34
+ ```
35
+
36
+ ## Click by Element Selector (Not Coordinates)
37
+
38
+ ```python
39
+ # YES — element-based, resilient
40
+ auto.ButtonControl(Name="Find").Click()
41
+
42
+ # NO — coordinate-based, fragile
43
+ # pyautogui.click(517, 432)
44
+ ```
45
+
46
+ ## Retry Flaky Actions
47
+
48
+ ```python
49
+ for attempt in range(3):
50
+ try:
51
+ auto.ButtonControl(Name="Find").Click()
52
+ time.sleep(1)
53
+ if auto.ListControl(Name="Results").Exists(1): break
54
+ except Exception:
55
+ if attempt == 2: raise
56
+ time.sleep(2)
57
+ ```
58
+
59
+ ## Dismiss Popups (Check Before Major Actions)
60
+
61
+ ```python
62
+ popup = auto.WindowControl(searchDepth=1, RegexName=".*Error.*|.*Warning.*")
63
+ if popup.Exists(0.5):
64
+ close_btn = popup.ButtonControl(Name="Close")
65
+ ok_btn = popup.ButtonControl(Name="OK")
66
+ if close_btn.Exists(0.5):
67
+ close_btn.Click()
68
+ elif ok_btn.Exists(0.5):
69
+ ok_btn.Click()
70
+ ```
71
+
72
+ ## Output (Always Structured JSON)
73
+
74
+ ```python
75
+ print(json.dumps({"status": "success", "patient": name, "data": results}))
76
+ ```
77
+
78
+ ## Mixed Browser + Desktop
79
+
80
+ Some browser automations need the physical screen (OS alerts, file upload dialogs, native file picker, CAPTCHA). These **cannot use `/execute/browser`** — use `/execute` instead and treat as desktop automation.
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: rpa-testing-workflow
3
+ description: Mandatory testing workflow for RPA steps. Prescriptive tool call sequences for per-step testing through the Minicor executor, polling execution status, taking screenshots during runs, and end-to-end validation. Use EVERY TIME you build or modify RPA workflows.
4
+ category: general
5
+ tags: [testing, workflow, execution, validation, mandatory]
6
+ priority: 100
7
+ ---
8
+
9
+ # RPA Testing Workflow
10
+
11
+ This skill is MANDATORY. Every RPA step must be tested through the Minicor executor, not just `vm_execute_script`. Follow these exact sequences.
12
+
13
+ ## Why `vm_execute_script` Is Not Enough
14
+
15
+ `vm_execute_script` runs raw Python directly on the VM. It does NOT go through the Minicor workflow engine. This means:
16
+
17
+ - `{{config.username}}`, `{{config.password}}`, and all `{{config.*}}` variables are NOT resolved — they appear as literal text
18
+ - `data.input` interpolation does NOT work — the JS wrapper that injects input values is not executed
19
+ - `data.step_N.response` references to previous step outputs do NOT work
20
+ - The `lam.httpRequest` / `lam.rpa` dispatch wrapper is NOT executed
21
+ - Recording, execution tracking, and monitoring are NOT triggered
22
+
23
+ A script that passes via `vm_execute_script` can and WILL fail when run through `execute_workflow`. You MUST test through the real executor.
24
+
25
+ ## Per-Step Testing (After Each `create_rpa_flow`)
26
+
27
+ After saving a step with `create_rpa_flow`, IMMEDIATELY test it through Minicor:
28
+
29
+ ### Step 1: Run the step in isolation
30
+
31
+ ```
32
+ execute_workflow_async(
33
+ workflowId: <workflow_id>,
34
+ input: { ... real test data ... },
35
+ configurationId: <config_store_id>,
36
+ start_from_step: <this_step_order>,
37
+ end_at_step: <this_step_order>
38
+ )
39
+ ```
40
+
41
+ This runs ONLY this step through the real Minicor executor with config variable resolution and the JS wrapper.
42
+
43
+ ### Step 2: Poll execution status
44
+
45
+ ```
46
+ Loop every 5-10 seconds:
47
+ get_execution_status(workflowId, executionId)
48
+
49
+ While status is "RUNNING" or "PENDING":
50
+ - Take vm_screenshot to watch progress on the VM
51
+ - Continue polling
52
+
53
+ When status is "COMPLETED":
54
+ - Take vm_screenshot to verify final state
55
+ - Call get_full_execution to see step output and any recordings
56
+ - Proceed to next step
57
+
58
+ When status is "FAILED" or "ERROR":
59
+ - Take vm_screenshot to see the error state
60
+ - Call diagnose_execution for failure analysis
61
+ - Call get_full_execution for detailed error output
62
+ - Go to failure recovery (below)
63
+ ```
64
+
65
+ ### Step 3: Verify the result
66
+
67
+ After the step completes successfully:
68
+ - `vm_screenshot` to visually confirm the expected state
69
+ - Check the execution output via `get_full_execution` — verify the step produced the expected data
70
+ - If the step reads data, verify the output JSON is correct
71
+
72
+ ### Step 4: Only then proceed to the next step
73
+
74
+ Do NOT start writing the next step until the current one passes through the executor.
75
+
76
+ ## Failure Recovery
77
+
78
+ When a step fails through the Minicor executor:
79
+
80
+ 1. `diagnose_execution(workflowId, executionId)` — get failure analysis with hints
81
+ 2. `get_full_execution(workflowId, executionId)` — see stdout, stderr, exit code, recording
82
+ 3. `vm_screenshot` — see what state the VM is in
83
+ 4. Identify the cause:
84
+ - **Config variable not resolving?** Check the config store has the right properties
85
+ - **Data passing broken?** Check the JS wrapper interpolation — load `get_skill("data-passing-between-steps")`
86
+ - **Script error?** Fix the Python, but test the fix through the executor, NOT `vm_execute_script`
87
+ 5. `update_flow(flowId, program: <fixed_code>)` — update the step code
88
+ 6. Re-run `execute_workflow_async` with `start_from_step`/`end_at_step` again
89
+ 7. Repeat until the step passes through the executor
90
+
91
+ CRITICAL: Do NOT use `vm_execute_script` to "verify" a fix. The fix must pass through `execute_workflow_async`.
92
+
93
+ ## End-to-End Testing
94
+
95
+ After ALL steps pass individually through the executor:
96
+
97
+ ### Full workflow test
98
+
99
+ ```
100
+ execute_workflow_async(
101
+ workflowId: <workflow_id>,
102
+ input: { ... real production-like data ... },
103
+ configurationId: <config_store_id>
104
+ )
105
+ ```
106
+
107
+ No `start_from_step` / `end_at_step` — run the ENTIRE workflow.
108
+
109
+ ### Monitor the full run
110
+
111
+ ```
112
+ Loop every 5-10 seconds:
113
+ get_execution_status(workflowId, executionId)
114
+ vm_screenshot (every 2-3 polls to watch progress)
115
+
116
+ On completion:
117
+ get_full_execution to verify all steps produced correct output
118
+ vm_screenshot to verify final state
119
+
120
+ On failure:
121
+ diagnose_execution
122
+ Identify which step failed
123
+ Fix with update_flow
124
+ Re-run the FULL workflow (not just the failing step)
125
+ ```
126
+
127
+ ### Completion criteria
128
+
129
+ The workflow is NOT done until:
130
+ - `execute_workflow_async` returns with all steps in "COMPLETED" status
131
+ - The output data is correct (verify via `get_full_execution`)
132
+ - The VM is in the expected final state (verify via `vm_screenshot`)
133
+
134
+ For production workflows, also:
135
+ - Run the workflow a second time to verify idempotency
136
+ - Verify state verification passes (expectedPreState/expectedPostState)
137
+
138
+ ## Common Mistakes to Avoid
139
+
140
+ 1. **Testing with `vm_execute_script` and declaring done** — this is the #1 mistake. Always use `execute_workflow_async`.
141
+ 2. **Not using `configurationId`** — config variables only resolve when a config store is attached to the execution.
142
+ 3. **Fixing a script and testing with `vm_execute_script`** — even fixes must be verified through the executor.
143
+ 4. **Not polling `get_execution_status`** — the async execution runs in the background. You must poll to know when it finishes.
144
+ 5. **Skipping per-step testing** — testing only end-to-end makes it hard to isolate failures. Test each step individually first.
145
+ 6. **Not taking screenshots during execution** — screenshots while the workflow runs show you what's actually happening on the VM.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: session-keepalive
3
+ description: Patterns for keeping RPA sessions alive using scheduled agents, health checks, and auto-recovery. Detecting session timeouts, re-authentication sequences, monitoring agent setup. Use when hardening production workflows that depend on persistent app sessions.
4
+ category: general
5
+ tags: [session, keepalive, monitoring, scheduled, recovery, production]
6
+ priority: 8
7
+ ---
8
+
9
+ # Session Keepalive
10
+
11
+ Production RPA workflows depend on an active, authenticated session. Sessions time out. This skill covers how to detect and recover from session loss automatically.
12
+
13
+ ## The Problem
14
+
15
+ - Web apps log you out after inactivity (15-60 minutes typically)
16
+ - Desktop apps lock or disconnect after RDP session timeout
17
+ - Citrix sessions disconnect after idle periods
18
+ - Data workflows fail silently when the session is gone
19
+
20
+ ## Solution: Scheduled Health Check Agent
21
+
22
+ ### Step 1: Build a Smart Launch workflow
23
+
24
+ Load `get_skill("smart-launch-patterns")` and build a Smart Launch workflow first. This is the recovery mechanism.
25
+
26
+ ### Step 2: Create a scheduled monitoring agent
27
+
28
+ ```
29
+ create_agent(
30
+ name: "session-keepalive",
31
+ task: "Run the Smart Launch workflow to verify the session is active. If it fails, take a screenshot, diagnose, and report.",
32
+ mode: "scheduled",
33
+ cronSchedule: "*/5 * * * *",
34
+ workspaceId: <id>,
35
+ vmUrl: "<tunnel_url>",
36
+ watchWorkflowId: <smart_launch_workflow_id>
37
+ )
38
+ ```
39
+
40
+ ### Step 3: Add failure monitoring
41
+
42
+ ```
43
+ create_agent(
44
+ name: "session-monitor",
45
+ task: "When the Smart Launch fails, take a screenshot, check what went wrong, re-run Smart Launch, and notify Slack.",
46
+ mode: "monitor",
47
+ watchWorkflowId: <smart_launch_workflow_id>,
48
+ recoveryTask: "Take a screenshot. If login page is showing, the session expired — re-run Smart Launch. If the app crashed, restart it. Report results to Slack.",
49
+ slackWebhookUrl: "<webhook>",
50
+ workspaceId: <id>,
51
+ vmUrl: "<tunnel_url>"
52
+ )
53
+ ```
54
+
55
+ ## Detecting Session Loss
56
+
57
+ ### Browser (CDP)
58
+
59
+ ```python
60
+ # Check if still on the app page vs redirected to login
61
+ current_url = cdp_eval(ws, 'window.location.href')
62
+ if '/login' in current_url or '/lock' in current_url:
63
+ print("Session expired — need to re-authenticate")
64
+ ```
65
+
66
+ ### Desktop (uiautomation)
67
+
68
+ ```python
69
+ # Check if the expected signed-in element still exists
70
+ window = auto.WindowControl(searchDepth=1, Name='MyApp')
71
+ if not window.Exists(3):
72
+ print("App window gone — need to relaunch")
73
+ else:
74
+ signed_in_indicator = window.HyperlinkControl(Name='Dashboard')
75
+ if not signed_in_indicator.Exists(3):
76
+ print("Signed out — need to re-authenticate")
77
+ ```
78
+
79
+ ## Recovery Sequence
80
+
81
+ 1. Take a screenshot to document the failure state
82
+ 2. Run the Smart Launch workflow
83
+ 3. Verify the session is restored (check for the signed-in indicator)
84
+ 4. If still failing, try a full restart (close app, relaunch, login)
85
+ 5. Report results via Slack webhook or issue update
86
+
87
+ ## RDP/Citrix Session Management
88
+
89
+ For desktop automations that require an active RDP session:
90
+ - The VM's MDS handles this — it runs as a scheduled task in the interactive session
91
+ - If the RDP session disconnects, MDS continues running but UI automation may fail
92
+ - The health check detects this (window controls become unresponsive)
93
+ - Recovery: The VM service can trigger a reconnect via `start_mds_on_vm`
94
+
95
+ ## Production Checklist
96
+
97
+ - [ ] Smart Launch workflow built and tested
98
+ - [ ] Scheduled keepalive agent created (5-minute interval)
99
+ - [ ] Monitor agent watching Smart Launch for failures
100
+ - [ ] Slack notifications configured for failure alerts
101
+ - [ ] Recovery task handles all known failure modes (timeout, crash, disconnect)
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: smart-launch-patterns
3
+ description: Patterns for building Smart Launch workflows that ensure an app is running and authenticated before data workflows execute. Browser launch via CDP, desktop app launch via uiautomation, login/unlock detection, credential injection, MFA handling, popup dismissal. Use when building session management or app launch automation.
4
+ category: general
5
+ tags: [smart-launch, session, login, authentication, browser, desktop, cdp, mfa]
6
+ priority: 9
7
+ ---
8
+
9
+ # Smart Launch Patterns
10
+
11
+ A Smart Launch workflow ensures the target application is running and authenticated before any data workflow executes. Every production workspace needs one.
12
+
13
+ ## When to Build a Smart Launch
14
+
15
+ - **Production**: Always. Data workflows depend on an active session.
16
+ - **POC**: Skip it. Test with a manually opened app.
17
+
18
+ ## Browser Smart Launch (CDP)
19
+
20
+ Pattern from PracticeFusion (Hillside workspace):
21
+
22
+ ### Step 1: Check if browser is running
23
+
24
+ ```python
25
+ import urllib.request, json
26
+
27
+ def get_cdp_ws(tab_filter='myapp'):
28
+ try:
29
+ resp = urllib.request.urlopen('http://127.0.0.1:9222/json')
30
+ tabs = json.loads(resp.read())
31
+ for tab in tabs:
32
+ if tab_filter in tab.get('url', ''):
33
+ return tab['webSocketDebuggerUrl']
34
+ return tabs[0]['webSocketDebuggerUrl'] if tabs else None
35
+ except:
36
+ return None
37
+ ```
38
+
39
+ ### Step 2: Launch browser if not running
40
+
41
+ ```python
42
+ import subprocess, time
43
+
44
+ def launch_browser(url):
45
+ subprocess.Popen([
46
+ r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe',
47
+ '--remote-debugging-port=9222',
48
+ '--remote-allow-origins=*',
49
+ '--start-maximized',
50
+ '--no-first-run',
51
+ url
52
+ ])
53
+ time.sleep(8)
54
+ ```
55
+
56
+ ### Step 3: Detect state (login vs locked vs logged-in)
57
+
58
+ ```python
59
+ current_url = cdp_eval(ws, 'window.location.href')
60
+
61
+ if '/lock' in current_url:
62
+ # Screen locked — unlock with password
63
+ unlock_screen(ws, password)
64
+ elif '/login' in current_url:
65
+ # On login page — enter credentials
66
+ login(ws, username, password)
67
+ elif '/app/' in current_url:
68
+ # Already logged in — ready
69
+ pass
70
+ else:
71
+ # Unknown state — navigate to login
72
+ cdp_navigate(ws, login_url)
73
+ ```
74
+
75
+ ### Step 4: Inject credentials (React-safe)
76
+
77
+ Escape credentials before injecting into JS to handle special characters (`'`, `\`, etc.):
78
+
79
+ ```python
80
+ safe_user = username.replace('\\', '\\\\').replace("'", "\\'")
81
+ safe_pass = password.replace('\\', '\\\\').replace("'", "\\'")
82
+ ```
83
+
84
+ Then use the escaped values in the CDP eval:
85
+
86
+ ```python
87
+ cdp_eval(ws, f"""
88
+ (function() {{
89
+ var emailInput = document.querySelector('input[type="email"]');
90
+ var pwInput = document.querySelector('input[type="password"]');
91
+ var setter = Object.getOwnPropertyDescriptor(
92
+ window.HTMLInputElement.prototype, "value"
93
+ ).set;
94
+ if (emailInput) {{
95
+ setter.call(emailInput, '{username}');
96
+ emailInput.dispatchEvent(new Event('input', {{bubbles: true}}));
97
+ emailInput.dispatchEvent(new Event('change', {{bubbles: true}}));
98
+ }}
99
+ if (pwInput) {{
100
+ setter.call(pwInput, '{password}');
101
+ pwInput.dispatchEvent(new Event('input', {{bubbles: true}}));
102
+ pwInput.dispatchEvent(new Event('change', {{bubbles: true}}));
103
+ }}
104
+ var btns = document.querySelectorAll('button');
105
+ for (var i = 0; i < btns.length; i++) {{
106
+ if (btns[i].textContent.trim().toLowerCase().includes('log in')) {{
107
+ btns[i].click(); break;
108
+ }}
109
+ }}
110
+ }})();
111
+ """)
112
+ ```
113
+
114
+ ### Step 5: Handle MFA
115
+
116
+ After login, check if MFA is required:
117
+ - If URL contains 'securitycheck' or 'securitycode', MFA is needed
118
+ - Use `tfa_generate_totp` or `tfa_request_sms_otp` to get the code
119
+ - Inject the code via CDP
120
+
121
+ ## Desktop Smart Launch (uiautomation)
122
+
123
+ Pattern from athenaPractice (Novelle workspace):
124
+
125
+ ### Step 1: Check if window exists
126
+
127
+ ```python
128
+ import uiautomation as auto
129
+
130
+ win = auto.WindowControl(searchDepth=1, Name='athenaPractice')
131
+ window_exists = win.Exists(3)
132
+ ```
133
+
134
+ ### Step 2: Conditional launch
135
+
136
+ ```python
137
+ if not window_exists:
138
+ import subprocess, os
139
+ app_path = os.path.join(os.environ["PUBLIC"], "Desktop", "MyApp.lnk")
140
+ subprocess.Popen(["powershell", "-Command", f'Start-Process "{app_path}"'])
141
+ time.sleep(15)
142
+ ```
143
+
144
+ ### Step 3: Check if signed in
145
+
146
+ Look for a known UI element that only appears when logged in:
147
+
148
+ ```python
149
+ window = auto.WindowControl(searchDepth=1, Name='athenaPractice')
150
+ window.SetActive()
151
+
152
+ # Look for an element that proves we're signed in
153
+ chart = window.HyperlinkControl(Name='Chart')
154
+ signed_in = chart.Exists(3)
155
+
156
+ if not signed_in:
157
+ # Also try other control types
158
+ chart = window.TextControl(Name='Chart')
159
+ signed_in = chart.Exists(1)
160
+ ```
161
+
162
+ ### Step 4: Conditional login
163
+
164
+ Use data passing to skip steps that aren't needed:
165
+
166
+ ```javascript
167
+ (data) => {
168
+ const windowExists = data.step_1?.response?.resultData?.windowExists ?? false;
169
+ if (windowExists) {
170
+ return {"skipped": true, "message": "Window already exists"};
171
+ }
172
+ // Otherwise return the launch script
173
+ return { "lam.rpa": { script: launchScript, channelId: "{{config.channelId}}" } };
174
+ }
175
+ ```
176
+
177
+ ### Step 5: Dismiss popups
178
+
179
+ After login, dismiss any startup dialogs:
180
+
181
+ ```python
182
+ import time
183
+ time.sleep(3)
184
+ popup = auto.WindowControl(searchDepth=1, RegexName=".*Update.*|.*Notice.*|.*Alert.*")
185
+ if popup.Exists(2):
186
+ ok_btn = popup.ButtonControl(Name="OK") or popup.ButtonControl(Name="Close")
187
+ if ok_btn.Exists(1):
188
+ ok_btn.Click()
189
+ ```
190
+
191
+ ## Workflow Structure
192
+
193
+ A typical Smart Launch workflow has 4-6 steps:
194
+ 1. Check if app/browser is running
195
+ 2. Launch if not running
196
+ 3. Check if signed in
197
+ 4. Login if not signed in
198
+ 5. Handle MFA (if applicable)
199
+ 6. Dismiss popups
200
+
201
+ Use conditional execution via the JS wrapper — steps can return `{"skipped": true}` when not needed.
202
+
203
+ ## Config Store Setup
204
+
205
+ Smart Launch workflows reference credentials from config stores:
206
+ - `{{config.username}}` / `{{config.password}}` — app credentials
207
+ - `{{config.url}}` — login URL
208
+ - `{{config.channelId}}` — RPA channel ID for desktop dispatch
209
+ - `{{config.totp_secret_id}}` — for TOTP-based MFA
210
+
211
+ ## Health Check Pattern
212
+
213
+ Create a simple workflow that runs the Smart Launch and reports status. Schedule it via `create_agent mode: "scheduled"` with a cron expression (e.g., every 5 minutes). This keeps the session alive and auto-recovers from timeouts.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: state-verification
3
+ description: LLM-based UI state verification for RPA steps using expectedPreState and expectedPostState. How to use generate_state_description and debug_rpa_step for regression detection. Use when adding verification to RPA steps or debugging flaky automations.
4
+ category: general
5
+ tags: [verification, state, debugging, regression, screenshots]
6
+ priority: 7
7
+ ---
8
+
9
+ # State Verification
10
+
11
+ ## Overview
12
+
13
+ Every RPA step can include `expectedPreState` and `expectedPostState` — natural language descriptions of what the screen should look like before and after the step runs. The MDS uses LLM-based screenshot analysis to verify these conditions, catching regressions when the target app's UI changes.
14
+
15
+ ## Using `debug_rpa_step`
16
+
17
+ `debug_rpa_step` runs a script with full diagnostics:
18
+
19
+ - Takes a **before screenshot**
20
+ - Executes the script
21
+ - Takes an **after screenshot**
22
+ - Returns stdout, stderr, exit code, and both screenshots
23
+ - Optionally verifies against `expectedPreState` / `expectedPostState`
24
+
25
+ Use during development to validate each step before saving.
26
+
27
+ ## Writing State Descriptions
28
+
29
+ Use `generate_state_description` to author state descriptions from the current screen. Descriptions should be:
30
+
31
+ - **Specific enough** to catch real regressions (e.g., "The Patient Search dialog is open with an empty MRN field")
32
+ - **General enough** to not break on minor UI changes (e.g., don't mention exact pixel positions or colors)
33
+ - **Focused on the relevant area** — describe what matters for this step, not the entire screen
34
+
35
+ ## Workflow
36
+
37
+ 1. Navigate to the pre-state → `generate_state_description` → save as `expectedPreState`
38
+ 2. Run the automation step
39
+ 3. Verify the result → `generate_state_description` → save as `expectedPostState`
40
+ 4. Pass both to `create_rpa_flow` when saving the step
41
+
42
+ ## When State Verification Catches Issues
43
+
44
+ - App updated its UI (new buttons, moved fields, changed labels)
45
+ - Login session expired (expected app screen, got login page)
46
+ - Popup or error dialog appeared unexpectedly
47
+ - Previous step failed silently, leaving the app in wrong state
48
+
49
+ ## Debugging Tools
50
+
51
+ - `**debug_rpa_step`** — runs script with before/after screenshots + full diagnostics
52
+ - `**vm_reset_state`** — manage windows: focus an app, minimize all, close dialogs
53
+ - `**vm_read_clipboard**` — read clipboard after a copy operation
54
+ - `**vm_screenshot_region**` — crop/zoom a specific screen region
55
+ - `**batch_test_rpa**` — run the workflow with multiple test inputs
56
+ - **Video Recordings** — use `get_full_execution` to see recording references