@minicor/mcp-server 3.1.4 → 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 (55) 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 +2 -2
  43. package/dist/tools/vm.js.map +1 -1
  44. package/dist/tools/workflow-ops.js +1 -1
  45. package/dist/tools/workflow-ops.js.map +1 -1
  46. package/package.json +4 -2
  47. package/skills/general/cdp-browser-automation.md +97 -0
  48. package/skills/general/data-extraction-strategies.md +64 -0
  49. package/skills/general/data-hydration-patterns.md +167 -0
  50. package/skills/general/data-passing-between-steps.md +46 -0
  51. package/skills/general/desktop-uiautomation.md +80 -0
  52. package/skills/general/rpa-testing-workflow.md +145 -0
  53. package/skills/general/session-keepalive.md +101 -0
  54. package/skills/general/smart-launch-patterns.md +213 -0
  55. package/skills/general/state-verification.md +56 -0
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"build-rpa.d.ts","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QAqV5C"}
1
+ {"version":3,"file":"build-rpa.d.ts","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QA8J5C"}
@@ -12,13 +12,23 @@ export function register({ server }) {
12
12
  .string()
13
13
  .optional()
14
14
  .describe("Existing workflow ID to add steps to (omit to create a new workflow)"),
15
- }, async ({ workspaceId, task, appName, workflowId }) => ({
16
- messages: [
17
- {
18
- role: "user",
19
- content: {
20
- type: "text",
21
- text: `You are building an RPA workflow on the Minicor platform. Your goal is to iteratively create automation steps that run on a VM via the Minicor Desktop Service (MDS).
15
+ mode: z
16
+ .enum(["poc", "production"])
17
+ .optional()
18
+ .describe("'poc' for quick prototype (skip verification, minimal testing), 'production' for full hardening. If omitted, ask the user."),
19
+ }, async ({ workspaceId, task, appName, workflowId, mode }) => {
20
+ const isProduction = mode === "production";
21
+ const isPoc = mode === "poc";
22
+ const modeSection = mode
23
+ ? `\n**Mode: ${mode.toUpperCase()}**${isPoc ? " — Quick prototype, streamlined testing." : " — Full hardening with state verification, monitoring, and idempotency testing."}`
24
+ : `\n**Mode not specified.** Ask the user: "Is this a quick prototype (POC) or going to production?" Then adapt your approach accordingly.`;
25
+ return {
26
+ messages: [
27
+ {
28
+ role: "user",
29
+ content: {
30
+ type: "text",
31
+ text: `You are building an RPA workflow on the Minicor platform. Your goal is to iteratively create automation steps that run on a VM via the Minicor Desktop Service (MDS).
22
32
 
23
33
  ## Task
24
34
  ${task}
@@ -28,114 +38,47 @@ ${appName}
28
38
 
29
39
  ## Workspace
30
40
  ID: ${workspaceId}${workflowId ? `\nExisting workflow ID: ${workflowId} (add steps to this workflow)` : "\nCreate a new workflow for this automation."}
41
+ ${modeSection}
31
42
 
32
- ## CRITICAL RULES
33
-
34
- ### Rule 1 — MANDATORY VALIDATION
35
- **NEVER save a step without first validating it on the VM.** Every RPA script MUST pass this sequence:
36
- 1. \`vm_execute_script\` — run on the VM
37
- 2. \`vm_screenshot\` — visually confirm it worked
38
- 3. Only then → save via \`create_rpa_flow\`
39
-
40
- ### Rule 2 — USE \`create_rpa_flow\` TO SAVE (NOT \`create_flow\`)
41
- When saving an RPA step, call **\`create_rpa_flow\`** — it automatically wraps your Python script in the correct Minicor JS format. You only pass the Python script; the tool handles the \`lam.httpRequest\` / \`lam.rpa\` wrapper.
42
-
43
- **NEVER** call \`create_flow\` with raw Python for an RPA step. **NEVER** try to construct the JS wrapper yourself.
44
-
45
- ### Rule 3 — COMBINE ui_inspect + screenshots + clipboard
46
- Screenshots alone are unreliable for reading data (resolution issues, misreads). ALWAYS combine multiple methods. See the Data Extraction Strategy section below.
47
-
48
- ## Strategy Selection (BEFORE writing any automation)
49
-
50
- ### For Web/Browser Targets:
51
- - Use **CDP via Python websocket** for page manipulation (fastest, most reliable for anti-bot sites)
52
- - The MDS provides an isolated Chrome instance per execution via \`/execute/browser\`
53
- - Multiple browser automations run **in parallel** on the same VM — each gets its own Chrome
54
- - Scripts always use \`127.0.0.1:9222\` — the MDS transparently routes to the correct Chrome instance
55
- - Use CDP \`Page.captureScreenshot\` for screenshots within the browser tab
56
- - Check if the site has usable internal APIs (inspect network traffic via CDP \`fetch\` interception)
57
- - If clean APIs exist and are stable → consider direct \`requests\`/\`httpx\` instead of UI automation
58
- - If anti-bot protection exists (Cloudflare, reCAPTCHA) → CDP through the VM browser avoids detection
59
-
60
- ### For Desktop Targets:
61
- - **.NET / WPF / WinForms** → \`uiautomation\` (default) or \`pywinauto\`
62
- - **Java / Swing** → \`jab\` (Java Access Bridge)
63
- - **Electron / web-based desktop** → \`pywinauto\` or \`pyautogui\`
64
- - **Legacy Win32** → \`uiautomation\`
65
- - Start with \`uiautomation\` if unsure.
66
- - Desktop scripts use \`/execute\` and run **one at a time** per VM (the physical screen is shared)
67
-
68
- ### Mixed Browser + Desktop (IMPORTANT)
69
- Some browser automations need to interact with the physical screen — for example:
70
- - Clicking OS-level alerts or confirmation dialogs
71
- - File upload/download dialogs (native file picker)
72
- - Browser notifications or permission prompts
73
- - CAPTCHA solving that requires clicking outside the browser
74
-
75
- **These automations CANNOT use \`/execute/browser\`** because they need the screen, which is shared.
76
- Use \`/execute\` instead and treat them like desktop automations — they run one at a time per VM.
77
-
78
- When building a workflow, determine which category it falls into:
79
- - **Pure CDP** (all interaction via \`Runtime.evaluate\`, \`Page.navigate\`, etc.) → \`/execute/browser\` — parallel-safe
80
- - **Needs screen interaction** (any \`pyautogui\`, OS dialogs, file pickers) → \`/execute\` — one at a time
43
+ ## MANDATORY FIRST STEP — Load Testing Skill
81
44
 
82
- ## Browser Automation via CDP (Python WebSocket)
45
+ Before doing ANYTHING else, run: \`get_skill("rpa-testing-workflow")\`
83
46
 
84
- Your Python scripts connect to Chrome via the Chrome DevTools Protocol. The MDS handles Chrome lifecycle and port routing transparently — scripts always use port 9222.
47
+ This skill contains the exact tool call sequences you MUST follow for testing each step through the Minicor executor. \`vm_execute_script\` is for prototyping only — it does NOT test config variables, data passing, or the JS wrapper. Every step must pass through \`execute_workflow_async\`.
85
48
 
86
- **Dispatch:** Use \`dispatchPattern: "browser"\` when saving with \`create_rpa_flow\`. This routes to \`/execute/browser\` which provides an isolated Chrome instance.
87
-
88
- ### How CDP Works:
89
- 1. Discover tabs: \`GET http://127.0.0.1:9222/json\`
90
- 2. Connect via WebSocket to the target tab's \`webSocketDebuggerUrl\`
91
- 3. Use \`Runtime.evaluate\` to execute JavaScript in the page context
92
- 4. Use CDP \`Page.captureScreenshot\` for screenshots
93
-
94
- ### CDP Starter Template:
95
- \`\`\`python
96
- import json, websocket, time
97
- from urllib.request import urlopen
98
-
99
- tabs = json.loads(urlopen('http://127.0.0.1:9222/json').read())
100
- page_tab = [t for t in tabs if t.get('type') == 'page'][0]
101
- ws = websocket.create_connection(page_tab['webSocketDebuggerUrl'])
102
- cmd_id = 0
49
+ ## CRITICAL RULES
103
50
 
104
- def cdp_eval(ws, js):
105
- global cmd_id; cmd_id += 1
106
- ws.send(json.dumps({'id': cmd_id, 'method': 'Runtime.evaluate', 'params': {'expression': js}}))
107
- while True:
108
- msg = json.loads(ws.recv())
109
- if msg.get('id') == cmd_id: return msg
51
+ 1. **VALIDATE BEFORE SAVING** — Every RPA script MUST be tested on the VM (\`vm_execute_script\` or \`debug_rpa_step\`) and visually confirmed (\`vm_screenshot\`) before saving with \`create_rpa_flow\`.
52
+ 2. **USE \`create_rpa_flow\` TO SAVE** — Never call \`create_flow\` with raw Python for RPA. Never construct the JS wrapper yourself.
53
+ 3. **TEST EACH STEP THROUGH MINICOR** — After saving each step, run \`execute_workflow_async\` with \`start_from_step\`/\`end_at_step\` to test it through the real executor. Follow the testing skill exactly.
54
+ 4. **USE \`{{config.variables}}\` FOR SECRETS** — Never hardcode credentials.
55
+ 5. **COMBINE EXTRACTION METHODS** — Screenshots alone are unreliable for reading data. Always combine accessibility tree + clipboard + screenshots.
110
56
 
111
- # Navigate
112
- cdp_eval(ws, 'window.location.href="https://example.com"')
113
- time.sleep(8)
57
+ ## Skills — Load Before Writing Code
114
58
 
115
- # Fill input using React-safe setter (ALWAYS use this for React/Angular/Vue apps)
116
- cdp_eval(ws, 'var s=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set;var inp=document.querySelector("input[type=email]");if(inp){s.call(inp,"user@example.com");inp.dispatchEvent(new Event("input",{bubbles:true}));inp.dispatchEvent(new Event("change",{bubbles:true}))}')
59
+ Call \`list_skills\` to see available skills, then \`get_skill(name)\` to load detailed patterns:
60
+ - **MANDATORY** → \`get_skill("rpa-testing-workflow")\` — testing sequences for every step
61
+ - **Browser/CDP targets** → \`get_skill("cdp-browser-automation")\`
62
+ - **Desktop targets** → \`get_skill("desktop-uiautomation")\`
63
+ - **Data reading** → \`get_skill("data-extraction-strategies")\`
64
+ - **Multi-step data flow** → \`get_skill("data-passing-between-steps")\`${isProduction ? `\n- **State verification** → \`get_skill("state-verification")\` — REQUIRED for production workflows` : isPoc ? "" : `\n- **State verification** → \`get_skill("state-verification")\` — load if building for production`}
65
+ - Check \`list_skills()\` for customer/task-specific skills for this workspace
117
66
 
118
- # Click button by text content (more resilient than CSS selectors)
119
- cdp_eval(ws, 'document.querySelectorAll("button").forEach(function(b){if(b.textContent.trim()==="Submit"){b.click()}})')
67
+ ## Strategy Selection
120
68
 
121
- ws.close()
122
- \`\`\`
69
+ ### Web/Browser Targets:
70
+ - Use **CDP via Python websocket** — load \`cdp-browser-automation\` skill for patterns
71
+ - MDS provides isolated Chrome per execution via \`/execute/browser\` (parallel-safe)
72
+ - Scripts always use \`127.0.0.1:9222\` — MDS routes transparently
73
+ - Check for usable internal APIs (CDP \`fetch\` interception) before UI automation
123
74
 
124
- ### Key CDP Patterns:
125
- - **React-safe value setter**: Always use \`Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set\` — direct \`.value=\` assignment does NOT trigger React/Angular change detection
126
- - **Button clicks by text**: Use \`querySelectorAll("button").forEach()\` + \`textContent.trim()\` matching — more resilient than IDs or classes that change
127
- - **Credentials**: Use \`\\\${username}\` / \`\\\${password}\` interpolated from JS wrapper variables sourced from \`{{config.xxx}}\` — NEVER hardcode
128
- - **Waits**: \`time.sleep()\` between navigations (8-15s for page loads, 1-3s for UI actions)
129
- - **Verification**: Use CDP \`Page.captureScreenshot\` for per-tab screenshots
130
- - **Dropdown handling**: Click to open, then use \`querySelectorAll\` to find options by text and click
131
- - **Tab management**: If multiple tabs open, filter \`/json\` response by URL or title
75
+ ### Desktop Targets:
76
+ - **.NET/WPF/WinForms** → \`uiautomation\` | **Java/Swing** → \`jab\` | **Electron** → \`pywinauto\` | **Legacy** → \`uiautomation\`
77
+ - Load \`desktop-uiautomation\` skill for element-based patterns
78
+ - Desktop scripts use \`/execute\` — one at a time per VM (shared screen)
132
79
 
133
- ### Parallel Execution Notes:
134
- - \`/execute/browser\` runs your script with its own Chrome instance — multiple workflows can run at the same time on one VM
135
- - \`/execute\` runs your script without Chrome — for desktop automation or mixed browser+desktop scripts
136
- - The MDS transparently rewrites \`127.0.0.1:9222\` in your script to the correct Chrome port — you never need to handle ports
137
- - Recordings from \`/execute/browser\` capture only the browser tab (CDP screencast), not the full desktop
138
- - Recordings from \`/execute\` capture the full desktop (MSS screen recording)
80
+ ### Mixed Browser + Desktop:
81
+ - Needs screen (OS dialogs, file pickers, CAPTCHA) → use \`/execute\`, NOT \`/execute/browser\`
139
82
 
140
83
  ## Procedure
141
84
 
@@ -143,9 +86,9 @@ ws.close()
143
86
  If no VM is connected, ask for the **Cloudflare Tunnel URL** and call \`vm_connect\`.
144
87
 
145
88
  ### 2. Research the Target Application
146
- Based on "${appName}", determine if it's a **web/browser** target or a **desktop** target using the Strategy Selection above.
89
+ Based on "${appName}", determine if it's a web/browser or desktop target.
147
90
 
148
- ### 3. Initial Survey (ALWAYS do this first)
91
+ ### 3. Initial Survey
149
92
  Before writing any automation:
150
93
  1. \`vm_screenshot\` — see the desktop state
151
94
  2. \`vm_inspect_ui\` mode \`screen_info\` — get resolution
@@ -154,180 +97,51 @@ Before writing any automation:
154
97
 
155
98
  ### 4. Iterative Build Loop — For EACH step:
156
99
 
157
- **a. OBSERVE — Understand the current state (REQUIRED)**
158
- - \`vm_screenshot\` to see the screen
159
- - \`vm_inspect_ui\` with \`element_tree\` to map UI elements
160
- - \`vm_inspect_ui\` with \`element_at_point\` for specific elements
161
-
162
- **b. WRITE — Create the Python RPA script**
163
- - Use the appropriate framework (pyautogui for mouse/keyboard, uiautomation/pywinauto for element-based)
164
- - Include error handling and waits
165
- - Explain what it does before executing
166
-
167
- **c. VALIDATE — Test on the VM (REQUIRED)**
168
- - \`vm_execute_script\` — run the script
169
- - Or use \`debug_rpa_step\` for full before/after screenshots + diagnostics
170
- - Fix and re-run if errors occur
171
-
172
- **d. VERIFY — Confirm visually (REQUIRED)**
173
- - \`vm_screenshot\` immediately after
174
- - If result is wrong, go back to (b)
175
-
176
- **e. SAVE — Call \`create_rpa_flow\` (only after c + d pass) — then test it through Minicor individually**
177
- - After saving, run \`execute_workflow_async\` with \`start_from_step\`/\`end_at_step\` to isolate this step
178
- - Poll \`get_execution_status\`, then \`vm_screenshot\` to verify the Minicor-executed result
179
- - Only proceed to the next step once this one passes through the real executor
180
- - Pass the validated Python script, step name, description, flowId, and executionOrder
181
- - The tool handles all JS wrapping automatically
182
- - For browser/CDP automations: set \`dispatchPattern: "browser"\` — routes to \`/execute/browser\` (parallel-safe)
183
- - For desktop automations: use default \`dispatchPattern: "cloudflare_tunnel"\` — routes to \`/execute\`
184
- - For mixed browser+desktop: use default \`dispatchPattern: "cloudflare_tunnel"\` — runs one at a time
185
-
186
- ### 5. Data Passing Between Steps (CRITICAL)
187
-
188
- Workflow input is available as \`data.input\` in the **JS wrapper**, NOT in Python directly. Dynamic values must be interpolated in the JS layer, then embedded into the Python template literal.
189
-
190
- **CORRECT — JS-layer interpolation (how the existing SOAP workflow does it):**
191
- \`\`\`javascript
192
- (data) => {
193
- const mrn = data?.input?.mrn || "DEFAULT";
194
- const pythonScript = \\\`
195
- mrn = "\${mrn}"
196
- # ... rest of Python script uses mrn variable
197
- \\\`;
198
- return { "lam.httpRequest": { ... body: { script: pythonScript } } };
199
- }
200
- \`\`\`
201
-
202
- **WRONG — Python template vars (will show literal text, not resolved):**
203
- \`\`\`python
204
- mrn = "{{input.mrn}}" # WRONG — this is not a config variable
205
- mrn = data.input.mrn # WRONG — data object doesn't exist in Python
206
- \`\`\`
207
-
208
- \`create_rpa_flow\` generates the JS wrapper automatically, but if the script needs dynamic input from \`data.input\` or \`data.step_N\`, you must construct the JS wrapper yourself or update the flow after creation to add JS-layer const declarations that interpolate values into the Python template literal.
100
+ **a. OBSERVE** — \`vm_screenshot\` + \`vm_inspect_ui\` (\`element_tree\`, \`element_at_point\`)
209
101
 
210
- **Config variables** like \`{{config.username}}\` ARE resolved by the workflow engine and work in both JS and Python layers. Use these for credentials and environment URLs.
102
+ **b. WRITE** — Create Python script using patterns from the relevant loaded skill
211
103
 
212
- **Previous step outputs** are at \`data.step_N.response\` (for HTTP/RPA steps) or \`data.step_N.data\` (for GENERAL_FUNCTION steps).
104
+ **c. VALIDATE** — \`vm_execute_script\` or \`debug_rpa_step\` — fix and re-run if errors
213
105
 
214
- ### 6. Test Through Minicor (REQUIRED — vm_execute_script is NOT enough)
106
+ **d. VERIFY** — \`vm_screenshot\` immediately after — go back to (b) if wrong
215
107
 
216
- \`vm_execute_script\` is for **prototyping only**. Scripts that pass on the VM may FAIL when run through Minicor because:
217
- - \`{{config.xxx}}\` variables only resolve in the workflow engine
218
- - \`data.input\` interpolation only works through the JS wrapper
219
- - Step-to-step data flow (\`data.step_N\`) only works in the real executor
108
+ **e. SAVE + TEST THROUGH MINICOR** — \`create_rpa_flow\` (only after c + d pass), then follow the \`rpa-testing-workflow\` skill:
109
+ - \`execute_workflow_async\` with \`start_from_step\`/\`end_at_step\` to isolate this step
110
+ - Poll \`get_execution_status\` every 5-10s + \`vm_screenshot\` to watch progress
111
+ - On failure: \`diagnose_execution\`, fix with \`update_flow\`, re-test through executor (NOT \`vm_execute_script\`)
112
+ - Only proceed to next step when this one passes through the real executor
113
+ - Browser/CDP: \`dispatchPattern: "browser"\` | Desktop: \`"cloudflare_tunnel"\` (default)
220
114
 
221
- **After saving ALL steps, you MUST test end-to-end through Minicor:**
115
+ ### 5. Data Passing Between Steps
116
+ Load \`get_skill("data-passing-between-steps")\` for the full guide. Key rule: \`data.input\` lives in the JS wrapper, not Python. Use JS-layer interpolation for dynamic values. \`{{config.xxx}}\` works in both layers.
222
117
 
223
- a. \`execute_workflow_async\` with **real input data** and a **configurationId** — use async so you can monitor
224
- a2. Poll \`get_execution_status\` every 5-10s and take \`vm_screenshot\` at intervals to observe progress
225
- b. If a step fails → \`diagnose_execution\` + \`vm_screenshot\` to identify the issue
226
- c. Use \`test_workflow_step\` to re-run individual failing steps through Minicor (NOT \`vm_execute_script\`)
227
- d. Fix with \`update_flow\`, then re-test through \`execute_workflow\` again
228
- e. Iterate until the **full workflow passes end-to-end** through \`execute_workflow\`
229
-
230
- **Do NOT declare a workflow complete until it passes \`execute_workflow\` with real inputs.**
118
+ ### 6. End-to-End Test Through Minicor
119
+ a. \`execute_workflow_async\` with real inputs + \`configurationId\` — no \`start_from_step\`/\`end_at_step\`
120
+ b. Poll \`get_execution_status\` every 5-10s, \`vm_screenshot\` at intervals to watch progress
121
+ c. On failure → \`diagnose_execution\` + \`vm_screenshot\`, fix with \`update_flow\`, re-run FULL workflow
122
+ d. Iterate until full workflow passes. **Do NOT declare done until it passes.**${isProduction ? "\ne. Run the workflow a SECOND time to verify idempotency." : ""}
231
123
 
232
124
  ### 7. Iterate with the User
233
- - Present completed workflow summary with execution results from Minicor
234
- - Make adjustments, re-validate changed steps through \`execute_workflow\`
235
-
236
- ### 8. Offer Agent Setup
237
- After a workflow passes end-to-end, offer to create an agent to manage it:
238
-
239
- "Workflow is working. Want me to set up a monitoring agent? It can:
240
- - **Watch for failures** and auto-recover (monitor mode)
241
- - **Run on a schedule** (scheduled mode, e.g. daily at 9am)
242
- - **Notify Slack** when runs complete or fail"
243
-
244
- If the user agrees, call \`create_agent\` with:
245
- - \`mode: "monitor"\` + \`watchWorkflowId\` for failure monitoring
246
- - \`mode: "scheduled"\` + a cron expression for recurring runs
247
- - \`task\`: describe the recovery/check behavior (e.g. "When this workflow fails, take a screenshot, check if the login expired, and re-run")
248
- - \`vmUrl\`: the same VM URL used during the build
249
- - Same \`workspaceId\`
250
-
251
- ## Data Extraction Strategy
252
-
253
- When you need to READ data from the screen (not just click/type), follow this priority order. **Do NOT rely solely on screenshots for data reading.**
254
-
255
- ### Priority 1: Accessibility Tree (most reliable)
256
- - \`vm_inspect_ui\` with \`element_tree\` on the target window
257
- - If the tree exposes text values, this is the most reliable method
258
- - Use \`element_at_point\` for specific fields
259
- - Use \`focused_element\` to read the current field
260
-
261
- ### Priority 2: Open Accessible Dialogs
262
- - Many apps expose more data when you open edit/detail dialogs
263
- - Double-click on a row or click "Edit" to open a modal — the modal often has better accessibility support
264
- - Then use \`element_tree\` on the modal
265
-
266
- ### Priority 3: Clipboard Extraction
267
- - Use \`vm_execute_script\` to click a field, then Ctrl+A, Ctrl+C
268
- - Call \`vm_read_clipboard\` to get the copied text
269
- - Works for individual fields, text areas, and some grid cells
270
-
271
- ### Priority 4: Keyboard Navigation
272
- - Tab through fields, reading each via \`vm_inspect_ui\` \`focused_element\`
273
- - Useful when the accessibility tree returns element structure but not values
274
-
275
- ### Priority 5: Zoomed Screenshot
276
- - Use \`vm_screenshot_region\` to crop a specific area for better resolution
277
- - Only for small text that can't be accessed any other way
278
-
279
- ### Priority 6: Alternative Application Paths
280
- - Think creatively! Look for:
281
- - Reports or Print menus that export data
282
- - List/Search views with better accessibility
283
- - CLI tools or command-line interfaces the app provides
284
- - Export to CSV/clipboard options
285
- - Alternative windows/dialogs that show the same data more accessibly
286
- - Use \`vm_execute_script\` to run Python code that queries the app's data directly if a CLI or API exists
287
-
288
- ### Priority 7: Full Screenshot (VERIFICATION ONLY)
289
- - Full desktop screenshots are for **verifying actions worked**, NOT for reading data
290
- - If you must use a screenshot to read data, acknowledge it's unreliable and suggest a better approach to the user
291
-
292
- ## Debugging Tools
293
-
294
- - **\`debug_rpa_step\`** — runs a script with before/after screenshots and full diagnostics (stdout, stderr, exit code). Use during development.
295
- - **\`vm_reset_state\`** — Manage windows: focus an app, minimize all, close dialogs, or close an app. Use before testing.
296
- - **\`vm_read_clipboard\`** — read clipboard after a copy operation.
297
- - **\`vm_screenshot_region\`** — crop/zoom a specific screen region for better text reading or verifying specific UI elements.
298
- - **\`batch_test_rpa\`** — run the workflow with multiple test inputs.
299
- - **Video Recordings** — Minicor records MP4 videos of each RPA step execution. Use \`get_full_execution\` to see recording references (\`recording.blobName\`). These can be viewed in the Minicor platform for visual debugging.
300
-
301
- ## State Reset (Idempotency)
302
-
303
- The workflow MUST return the system to its original state so it can run repeatedly:
304
- - Last step must reset — close dialogs, navigate back to the starting screen
305
- - Don't include login/window-opening — those belong in a separate setup workflow
306
- - After a successful run, immediately re-run to verify idempotency
307
-
308
- ## Context Persistence
309
-
310
- Use \`create_issue\` / \`update_issue\` to persist learned context across builds:
311
- - \`[Agent:<name>] Rules\` — app-specific behaviors (e.g., "Reports tab takes 15s to load")
312
- - \`[Agent:<name>] Context\` — persistent facts (URLs, credential rotation dates)
313
- - Read these at the start of future builds to avoid re-learning things
314
-
315
- ## Important Rules
316
- - **VALIDATE BEFORE SAVING** — no exceptions unless user explicitly opts out
317
- - **TEST THROUGH MINICOR** — \`vm_execute_script\` is for prototyping. Always run \`execute_workflow\` with real inputs before declaring done.
318
- - **Use \`create_rpa_flow\`** — never construct JS wrappers manually
319
- - **Use \`{{config.variables}}\` for secrets** — never hardcode credentials
320
- - **Last step = workflow output** — The workflow returns whatever the FINAL step produces. If you need structured data returned (JSON, extracted records), the last step must output it. Don't put meaningful data in step N and cleanup in step N+1. Combine cleanup + data return in the last step, or add a GENERAL_FUNCTION step after RPA that formats the final result.
321
- - **Study existing workflows first** — Before building, check if similar workflows exist in the workspace via \`get_workflow_overview\`. Reuse proven patterns for JS wrapper data passing, coordinate discovery, and framework selection. Existing workflows are battle-tested — copy their interpolation patterns.
322
- - **Combine extraction methods** — accessibility tree + clipboard + screenshots
323
- - **Start simple** — get basic automation working before adding sophistication
324
- - **Add waits** — use \`time.sleep()\` or element-wait patterns between actions
325
- - **Handle errors** — try/except with meaningful messages
326
- - **Keep scripts focused** — one logical action per step
327
- - **Reset to original state** — every workflow must be idempotent (see State Reset section above)`,
125
+ ${isProduction ? `
126
+ ### 8. Production Hardening
127
+ - Load \`get_skill("state-verification")\` and add \`expectedPreState\`/\`expectedPostState\` to each step
128
+ - Set up monitoring: \`create_agent\` with \`mode: "monitor"\` + \`watchWorkflowId\`
129
+ - Or schedule: \`create_agent\` with \`mode: "scheduled"\` + cron expression
130
+ - Persist learned context: \`create_issue\` with \`[Agent:<name>] Rules|Context\`
131
+ ` : isPoc ? "" : `
132
+ ### 8. Offer Production Setup
133
+ After e2e pass, ask: "Want me to harden this for production? I can add state verification, monitoring, and idempotency testing."
134
+ If yes, load \`get_skill("state-verification")\` and \`create_agent\` with \`mode: "monitor"\` + \`watchWorkflowId\`.
135
+ `}
136
+ ## Additional Rules
137
+ - **Study existing workflows first** — \`get_workflow_overview\` to find and reuse proven patterns
138
+ - **Last step = workflow output** — combine cleanup + data return in the final step${isProduction ? "\n- **Idempotency** — last step must reset state so workflow runs repeatedly" : ""}
139
+ - **Context persistence** — use \`create_issue\` / \`update_issue\` with \`[Agent:<name>] Rules|Context\` for cross-build learning
140
+ - **After successful build** — call \`generate_skill\` to extract reusable patterns, then \`save_skill\` to persist for future builds`,
141
+ },
328
142
  },
329
- },
330
- ],
331
- }));
143
+ ],
144
+ };
145
+ });
332
146
  }
333
147
  //# sourceMappingURL=build-rpa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-rpa.js","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,wSAAwS,EACxS;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CACP,iHAAiH,CAClH;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,uFAAuF,CACxF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sEAAsE,CACvE;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;EAGhB,IAAI;;;EAGJ,OAAO;;;MAGH,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,2BAA2B,UAAU,+BAA+B,CAAC,CAAC,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoH1I,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kGAqL+E;iBACvF;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"build-rpa.js","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,wSAAwS,EACxS;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CACP,iHAAiH,CAClH;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,uFAAuF,CACxF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sEAAsE,CACvE;QACH,IAAI,EAAE,CAAC;aACJ,IAAI,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;aAC3B,QAAQ,EAAE;aACV,QAAQ,CACP,4HAA4H,CAC7H;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE;QACzD,MAAM,YAAY,GAAG,IAAI,KAAK,YAAY,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC;QAC7B,MAAM,WAAW,GAAG,IAAI;YACtB,CAAC,CAAC,aAAa,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,iFAAiF,EAAE;YAC9K,CAAC,CAAC,yIAAyI,CAAC;QAE9I,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;;;EAGlB,IAAI;;;EAGJ,OAAO;;;MAGH,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,2BAA2B,UAAU,+BAA+B,CAAC,CAAC,CAAC,8CAA8C;EACpJ,WAAW;;;;;;;;;;;;;;;;;;;;;;;0EAuB6D,YAAY,CAAC,CAAC,CAAC,sGAAsG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oGAAoG;;;;;;;;;;;;;;;;;;;;;;;;;YAyBvS,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iFAiC8D,YAAY,CAAC,CAAC,CAAC,4DAA4D,CAAC,CAAC,CAAC,EAAE;;;EAG/J,YAAY,CAAC,CAAC,CAAC;;;;;;CAMhB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;;;;CAIhB;;;qFAGoF,YAAY,CAAC,CAAC,CAAC,8EAA8E,CAAC,CAAC,CAAC,EAAE;;sIAEjD;qBACzH;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -34,7 +34,7 @@ export function register({ server, client }) {
34
34
  role: "user",
35
35
  content: {
36
36
  type: "text",
37
- text: `Please debug this Laminar workflow execution.
37
+ text: `Please debug this Minicor workflow execution.
38
38
 
39
39
  ## Workflow Flows (Steps):
40
40
  ${json(flowsData)}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Seed the skills service with bundled general skills.
4
+ *
5
+ * Usage:
6
+ * SKILLS_ADMIN_KEY=xxx npx minicor-seed-skills
7
+ *
8
+ * Uses your stored Minicor auth token (~/.minicor/tokens.json) to
9
+ * authenticate through the frontend proxy, and the admin key to
10
+ * authorize writes to the global scope.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=seed-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-skills.d.ts","sourceRoot":"","sources":["../src/seed-skills.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Seed the skills service with bundled general skills.
4
+ *
5
+ * Usage:
6
+ * SKILLS_ADMIN_KEY=xxx npx minicor-seed-skills
7
+ *
8
+ * Uses your stored Minicor auth token (~/.minicor/tokens.json) to
9
+ * authenticate through the frontend proxy, and the admin key to
10
+ * authorize writes to the global scope.
11
+ */
12
+ import fs from "node:fs";
13
+ import { loadAllSkills } from "./skills.js";
14
+ import { apiToPlatformBase } from "./agent-service-client.js";
15
+ import { getTokenPath } from "./paths.js";
16
+ const adminKey = process.env.SKILLS_ADMIN_KEY;
17
+ if (!adminKey) {
18
+ console.error("SKILLS_ADMIN_KEY is required");
19
+ process.exit(1);
20
+ }
21
+ function loadAuthToken() {
22
+ try {
23
+ const tokenPath = getTokenPath();
24
+ if (!fs.existsSync(tokenPath))
25
+ return null;
26
+ const raw = JSON.parse(fs.readFileSync(tokenPath, "utf-8"));
27
+ const region = raw.us || raw.ca || raw;
28
+ if (!region?.access_token)
29
+ return null;
30
+ return {
31
+ token: region.access_token,
32
+ apiBase: region.api_base || "https://api.laminar.run",
33
+ };
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ async function main() {
40
+ const auth = loadAuthToken();
41
+ if (!auth) {
42
+ console.error("No stored auth token found. Run `minicor-mcp-setup` first.");
43
+ process.exit(1);
44
+ }
45
+ const skills = loadAllSkills();
46
+ console.log(`Found ${skills.length} bundled skills to seed`);
47
+ const payload = skills.map((s) => ({
48
+ scope: "global",
49
+ name: s.name,
50
+ description: s.description,
51
+ category: s.category,
52
+ tags: s.tags,
53
+ priority: s.priority,
54
+ content: s.content,
55
+ }));
56
+ const platformBase = apiToPlatformBase(auth.apiBase);
57
+ const url = `${platformBase}/api/agents/skills/seed`;
58
+ console.log(`Seeding to ${url}...`);
59
+ const res = await fetch(url, {
60
+ method: "POST",
61
+ headers: {
62
+ "Content-Type": "application/json",
63
+ Authorization: `Bearer ${auth.token}`,
64
+ "X-Admin-Key": adminKey,
65
+ },
66
+ body: JSON.stringify({ skills: payload }),
67
+ });
68
+ if (!res.ok) {
69
+ console.error(`Seed failed: ${res.status} ${await res.text()}`);
70
+ process.exit(1);
71
+ }
72
+ const result = await res.json();
73
+ console.log(`Seeded ${result.seeded} skills:`);
74
+ for (const s of result.skills) {
75
+ console.log(` - ${s.name} (${s.scope}) v${s.version}`);
76
+ }
77
+ }
78
+ main().catch((err) => {
79
+ console.error("Seed error:", err);
80
+ process.exit(1);
81
+ });
82
+ //# sourceMappingURL=seed-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-skills.js","sourceRoot":"","sources":["../src/seed-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * HTTP client for the Skills Service.
3
+ *
4
+ * Routes through the frontend proxy: app.minicor.com/api/agents/skills/*
5
+ * The frontend's catch-all agents proxy forwards to the agent service /v1/skills/*.
6
+ * Auth: bearer token (same as the user's session token).
7
+ */
8
+ export interface SkillServiceIndex {
9
+ name: string;
10
+ description: string;
11
+ category: string;
12
+ tags: string[];
13
+ priority: number;
14
+ }
15
+ export interface SkillServiceFull extends SkillServiceIndex {
16
+ content: string;
17
+ scripts?: Record<string, string>;
18
+ customer?: string;
19
+ sourceWorkflows?: number[];
20
+ createdBy: string;
21
+ createdAt: number;
22
+ updatedAt: number;
23
+ version: number;
24
+ }
25
+ export declare class SkillsServiceClient {
26
+ private token;
27
+ private platformBase;
28
+ constructor(apiBase: string, token: string);
29
+ private get headers();
30
+ private url;
31
+ listSkills(opts?: {
32
+ scope?: string;
33
+ scopeId?: string;
34
+ tags?: string[];
35
+ }): Promise<SkillServiceIndex[]>;
36
+ getSkill(name: string, opts?: {
37
+ scope?: string;
38
+ scopeId?: string;
39
+ }): Promise<SkillServiceFull | null>;
40
+ saveSkill(scope: string, scopeId: string | undefined, skill: {
41
+ name: string;
42
+ description: string;
43
+ category: string;
44
+ tags: string[];
45
+ priority?: number;
46
+ content: string;
47
+ scripts?: Record<string, string>;
48
+ customer?: string;
49
+ sourceWorkflows?: number[];
50
+ createdBy?: string;
51
+ }): Promise<SkillServiceFull | null>;
52
+ deleteSkill(name: string, scope: string, scopeId?: string): Promise<boolean>;
53
+ }
54
+ //# sourceMappingURL=skills-service-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-service-client.d.ts","sourceRoot":"","sources":["../src/skills-service-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAK5B,OAAO,CAAC,KAAK;IAJf,OAAO,CAAC,YAAY,CAAS;gBAG3B,OAAO,EAAE,MAAM,EACP,KAAK,EAAE,MAAM;IAKvB,OAAO,KAAK,OAAO,GAKlB;IAED,OAAO,CAAC,GAAG;IAKL,UAAU,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAkB1B,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1C,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAkB7B,SAAS,CACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAe7B,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC;CAcpB"}