@minicor/mcp-server 3.9.1 → 4.1.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 (102) hide show
  1. package/README.md +145 -100
  2. package/dist/__tests__/dev-mode-draft.test.js +27 -19
  3. package/dist/__tests__/dev-mode-draft.test.js.map +1 -1
  4. package/dist/__tests__/discovery.test.d.ts +2 -0
  5. package/dist/__tests__/discovery.test.d.ts.map +1 -0
  6. package/dist/__tests__/{builder-discovery.test.js → discovery.test.js} +3 -3
  7. package/dist/__tests__/discovery.test.js.map +1 -0
  8. package/dist/__tests__/http-seal.test.d.ts +2 -0
  9. package/dist/__tests__/http-seal.test.d.ts.map +1 -0
  10. package/dist/__tests__/http-seal.test.js +40 -0
  11. package/dist/__tests__/http-seal.test.js.map +1 -0
  12. package/dist/__tests__/http-server.test.d.ts +7 -0
  13. package/dist/__tests__/http-server.test.d.ts.map +1 -0
  14. package/dist/__tests__/http-server.test.js +317 -0
  15. package/dist/__tests__/http-server.test.js.map +1 -0
  16. package/dist/__tests__/jobs-tools.test.d.ts +2 -0
  17. package/dist/__tests__/jobs-tools.test.d.ts.map +1 -0
  18. package/dist/__tests__/jobs-tools.test.js +337 -0
  19. package/dist/__tests__/jobs-tools.test.js.map +1 -0
  20. package/dist/__tests__/laminar-client.test.js +31 -31
  21. package/dist/__tests__/laminar-client.test.js.map +1 -1
  22. package/dist/__tests__/lib-dev-mode.test.js +2 -2
  23. package/dist/__tests__/lib-dev-mode.test.js.map +1 -1
  24. package/dist/__tests__/middleware-service-client.test.js +70 -0
  25. package/dist/__tests__/middleware-service-client.test.js.map +1 -1
  26. package/dist/__tests__/server-surface.test.d.ts +2 -0
  27. package/dist/__tests__/server-surface.test.d.ts.map +1 -0
  28. package/dist/__tests__/{server-profile.test.js → server-surface.test.js} +120 -100
  29. package/dist/__tests__/server-surface.test.js.map +1 -0
  30. package/dist/bootstrap.js +29 -0
  31. package/dist/bootstrap.js.map +1 -1
  32. package/dist/http-oauth.d.ts +60 -0
  33. package/dist/http-oauth.d.ts.map +1 -0
  34. package/dist/http-oauth.js +380 -0
  35. package/dist/http-oauth.js.map +1 -0
  36. package/dist/http-seal.d.ts +17 -0
  37. package/dist/http-seal.d.ts.map +1 -0
  38. package/dist/http-seal.js +63 -0
  39. package/dist/http-seal.js.map +1 -0
  40. package/dist/http-server.d.ts +29 -0
  41. package/dist/http-server.d.ts.map +1 -0
  42. package/dist/http-server.js +229 -0
  43. package/dist/http-server.js.map +1 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +12 -15
  46. package/dist/index.js.map +1 -1
  47. package/dist/laminar-client.d.ts +11 -14
  48. package/dist/laminar-client.d.ts.map +1 -1
  49. package/dist/laminar-client.js +25 -25
  50. package/dist/laminar-client.js.map +1 -1
  51. package/dist/lib.d.ts +6 -4
  52. package/dist/lib.d.ts.map +1 -1
  53. package/dist/lib.js +10 -10
  54. package/dist/lib.js.map +1 -1
  55. package/dist/middleware-service-client.d.ts +37 -2
  56. package/dist/middleware-service-client.d.ts.map +1 -1
  57. package/dist/middleware-service-client.js +43 -2
  58. package/dist/middleware-service-client.js.map +1 -1
  59. package/dist/prompts/build-rpa.d.ts.map +1 -1
  60. package/dist/prompts/build-rpa.js +2 -0
  61. package/dist/prompts/build-rpa.js.map +1 -1
  62. package/dist/server-surface.d.ts +23 -0
  63. package/dist/server-surface.d.ts.map +1 -0
  64. package/dist/server-surface.js +113 -0
  65. package/dist/server-surface.js.map +1 -0
  66. package/dist/setup.d.ts +1 -1
  67. package/dist/setup.js +3 -9
  68. package/dist/setup.js.map +1 -1
  69. package/dist/sync.js +34 -6
  70. package/dist/sync.js.map +1 -1
  71. package/dist/tools/core.js +1 -1
  72. package/dist/tools/core.js.map +1 -1
  73. package/dist/tools/dev-mode-draft.d.ts.map +1 -1
  74. package/dist/tools/dev-mode-draft.js +63 -49
  75. package/dist/tools/dev-mode-draft.js.map +1 -1
  76. package/dist/tools/{builder-discovery.d.ts → discovery.d.ts} +3 -3
  77. package/dist/tools/discovery.d.ts.map +1 -0
  78. package/dist/tools/{builder-discovery.js → discovery.js} +3 -3
  79. package/dist/tools/discovery.js.map +1 -0
  80. package/dist/tools/jobs.d.ts.map +1 -1
  81. package/dist/tools/jobs.js +296 -3
  82. package/dist/tools/jobs.js.map +1 -1
  83. package/dist/tools/vm.js +1 -1
  84. package/dist/tools/vm.js.map +1 -1
  85. package/package.json +3 -2
  86. package/skills/general/job-build-loop.md +166 -0
  87. package/dist/__tests__/builder-discovery.test.d.ts +0 -2
  88. package/dist/__tests__/builder-discovery.test.d.ts.map +0 -1
  89. package/dist/__tests__/builder-discovery.test.js.map +0 -1
  90. package/dist/__tests__/server-profile.test.d.ts +0 -2
  91. package/dist/__tests__/server-profile.test.d.ts.map +0 -1
  92. package/dist/__tests__/server-profile.test.js.map +0 -1
  93. package/dist/builder-index.d.ts +0 -3
  94. package/dist/builder-index.d.ts.map +0 -1
  95. package/dist/builder-index.js +0 -5
  96. package/dist/builder-index.js.map +0 -1
  97. package/dist/server-profile.d.ts +0 -11
  98. package/dist/server-profile.d.ts.map +0 -1
  99. package/dist/server-profile.js +0 -104
  100. package/dist/server-profile.js.map +0 -1
  101. package/dist/tools/builder-discovery.d.ts.map +0 -1
  102. package/dist/tools/builder-discovery.js.map +0 -1
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Minicor MCP Server
2
2
 
3
- Build, deploy, and debug VM-based browser and desktop automations from **Cursor** or **Claude Code**. The AI agent connects to your Windows VM, writes Python automation scripts, tests them through the Minicor executor, and deploys production-ready workflows with skills accumulated from every build.
3
+ Build, deploy, and debug VM-based browser and desktop automations from **Cursor** or **Claude Code**. The AI agent connects to your Windows VM, writes Python automation scripts, tests them through the Minicor executor, and deploys production-ready workflows - with skills accumulated from every build.
4
4
 
5
5
  ## Quick Start
6
6
 
7
7
  ### 1. Install
8
8
 
9
- **Cursor** add to `~/.cursor/mcp.json`:
9
+ **Cursor** - add to `~/.cursor/mcp.json`:
10
10
 
11
11
  ```json
12
12
  {
@@ -19,7 +19,7 @@ Build, deploy, and debug VM-based browser and desktop automations from **Cursor*
19
19
  }
20
20
  ```
21
21
 
22
- **Claude Code** no global install needed (npx always runs the latest):
22
+ **Claude Code** - no global install needed (npx always runs the latest):
23
23
 
24
24
  ```bash
25
25
  claude mcp add minicor -- npx -y @minicor/mcp-server
@@ -39,46 +39,49 @@ npx -y -p @minicor/mcp-server minicor-mcp-setup --cli
39
39
 
40
40
  > The package ships multiple commands. Always use `npx -p @minicor/mcp-server <command>` to run a specific one (`minicor-mcp-setup`, `minicor-bootstrap`, …). Running `npx @minicor/mcp-server` alone only starts the MCP server and ignores trailing arguments.
41
41
 
42
- ### Focused Builder MCP (optional)
42
+ ### Hosted MCP (cloud, no install)
43
43
 
44
- The package also includes `minicor-builder-mcp`, a focused server for workflow creation, Dev Mode drafts and execution controls, configuration stores, VM discovery, and Jobs. It shares the normal Minicor login and backend-owned draft state with the full server.
44
+ The same server also runs hosted at `https://mcp.minicor.com/mcp` (Streamable HTTP). Sign-in is your Minicor email/password through an OAuth flow - no API keys, no local tokens. The tool set matches the local server except for the tools that read and write your local disk (workspace clones, sessions, sync); those require the local install above.
45
45
 
46
- To add it alongside the normal Cursor MCP during setup:
46
+ **Claude (web / Desktop / mobile):**
47
+
48
+ 1. Go to **Settings > Connectors > Add custom connector**.
49
+ 2. Paste `https://mcp.minicor.com/mcp` and save. OAuth is auto-discovered - no client ID or secret.
50
+ 3. Claude opens the Minicor sign-in page. Enter your email, password, and region (US/Canada). Done - the connector acts as your account.
51
+
52
+ **Claude Code:**
47
53
 
48
54
  ```bash
49
- npx -y -p @minicor/mcp-server minicor-mcp-setup --with-builder
55
+ claude mcp add --transport http minicor-cloud https://mcp.minicor.com/mcp
50
56
  ```
51
57
 
52
- Or configure it directly:
58
+ Then run `/mcp` inside Claude Code to trigger the OAuth sign-in.
59
+
60
+ **Cursor** - add a URL-based entry to `~/.cursor/mcp.json` (Cursor prompts for the OAuth sign-in on first use):
53
61
 
54
62
  ```json
55
63
  {
56
64
  "mcpServers": {
57
- "minicor-builder": {
58
- "command": "npx",
59
- "args": ["-y", "-p", "@minicor/mcp-server", "minicor-builder-mcp"]
65
+ "minicor-cloud": {
66
+ "url": "https://mcp.minicor.com/mcp"
60
67
  }
61
68
  }
62
69
  }
63
70
  ```
64
71
 
65
- For Claude Code:
72
+ Access tokens expire within an hour and refresh automatically for up to 30 days; after that you sign in again. To self-host the same endpoint (or restrict sign-in to your email domain), see [docs/HOSTED.md](docs/HOSTED.md).
66
73
 
67
- ```bash
68
- claude mcp add minicor-builder -- npx -y -p @minicor/mcp-server minicor-builder-mcp
69
- ```
70
-
71
- Use the builder server while editing, testing, and publishing drafts, then switch back to `minicor` for the full tool surface. The builder uses standard MCP tools by default; code mode remains opt-in through `EXPERIMENTAL_USE_CODE_MODE=1`.
74
+ > Older installs may have a separate `minicor-builder` entry in their MCP config. That server was folded into `minicor`; re-running `minicor-mcp-setup` removes the stale entry.
72
75
 
73
76
  ### 3. Bootstrap Workspace (optional)
74
77
 
75
78
  After cloning a workspace, generate harness-specific config files:
76
79
 
77
80
  ```bash
78
- # For Claude Code creates CLAUDE.md + .claude/settings.local.json
81
+ # For Claude Code - creates CLAUDE.md + .claude/settings.local.json
79
82
  npx -y -p @minicor/mcp-server minicor-bootstrap claude-code --dir ./my-workspace
80
83
 
81
- # For Cursor creates .cursor/rules/workspace.mdc
84
+ # For Cursor - creates .cursor/rules/workspace.mdc
82
85
  npx -y -p @minicor/mcp-server minicor-bootstrap cursor --dir ./my-workspace
83
86
 
84
87
  # All harnesses at once
@@ -93,13 +96,12 @@ npx -y -p @minicor/mcp-server minicor-bootstrap all --dir ./my-workspace
93
96
 
94
97
  Remove the MCP server entry from your editor first:
95
98
 
96
- **Cursor** edit `~/.cursor/mcp.json` and remove `mcpServers.minicor`, `mcpServers.minicor-builder`, and any legacy `mcpServers.laminar` entry.
99
+ **Cursor** - edit `~/.cursor/mcp.json` and remove `mcpServers.minicor`, plus any legacy `mcpServers.laminar` or `mcpServers.minicor-builder` entry.
97
100
 
98
- **Claude Code** remove the registered server:
101
+ **Claude Code** - remove the registered server:
99
102
 
100
103
  ```bash
101
104
  claude mcp remove minicor
102
- claude mcp remove minicor-builder
103
105
  ```
104
106
 
105
107
  If the command is unavailable, remove the `minicor` MCP server entry from your Claude Code MCP config.
@@ -199,7 +201,7 @@ Sessions are synced to `[Workspace:Session]` issues on the platform, so agents o
199
201
 
200
202
  ## The RPA Lifecycle
201
203
 
202
- This is the complete flow from zero to production automation. The agent handles each phase using MCP tools and skills.
204
+ This is the complete flow from zero to production automation. The agent handles each phase using MCP tools and skills. Workflows are built and tested inside a **Job** (see [Jobs](#jobs-rpa-orchestration) below): the job's test cases are written before the workflow exists and are the definition of done for the whole build.
203
205
 
204
206
  ### Phase 1: Workspace Setup
205
207
 
@@ -207,11 +209,11 @@ This is the complete flow from zero to production automation. The agent handles
207
209
  "Create a workspace for Acme Corp and set up a VM"
208
210
  ```
209
211
 
210
- - `create_workspace` / `list_workspaces` / `get_workspace` create or find a workspace
211
- - `vm_list` discover available VMs
212
- - `deploy_vm` provision a new Windows VM if needed
213
- - `install_mds_on_vm` / `start_mds_on_vm` install the Minicor Desktop Service
214
- - `vm_connect` connect to the VM via Cloudflare tunnel
212
+ - `create_workspace` / `list_workspaces` / `get_workspace` - create or find a workspace
213
+ - `vm_list` - discover available VMs
214
+ - `deploy_vm` - provision a new Windows VM if needed
215
+ - `install_mds_on_vm` / `start_mds_on_vm` - install the Minicor Desktop Service
216
+ - `vm_connect` - connect to the VM via Cloudflare tunnel
215
217
 
216
218
  ### Phase 2: Clone Workspace
217
219
 
@@ -219,18 +221,18 @@ This is the complete flow from zero to production automation. The agent handles
219
221
  "Clone workspace 257 to my local folder"
220
222
  ```
221
223
 
222
- - `clone_workspace` pulls everything to a local folder:
223
- - `minicor.json` workspace manifest
224
- - `workflows/` all workflow steps as files (git-native)
225
- - `.minicor/skills/general/` bundled RPA skills
226
- - `.minicor/skills/workspace/` workspace-specific learned skills
227
- - `.minicor/issues/` agent-persisted context from previous runs
228
- - `.minicor/skill-index.json` compact skill summary
229
- - `.minicor/workspace.json` workspace metadata
224
+ - `clone_workspace` - pulls everything to a local folder:
225
+ - `minicor.json` - workspace manifest
226
+ - `workflows/` - all workflow steps as files (git-native)
227
+ - `.minicor/skills/general/` - bundled RPA skills
228
+ - `.minicor/skills/workspace/` - workspace-specific learned skills
229
+ - `.minicor/issues/` - agent-persisted context from previous runs
230
+ - `.minicor/skill-index.json` - compact skill summary
231
+ - `.minicor/workspace.json` - workspace metadata
230
232
 
231
233
  The folder is git-ready. Push to GitHub for version control, diffs, and CI/CD.
232
234
 
233
- ### Phase 3: Scope & Research
235
+ ### Phase 3: Scope & Define the Green-Gate
234
236
 
235
237
  ```
236
238
  "I want to automate patient lookup in Centricity"
@@ -239,37 +241,45 @@ The folder is git-ready. Push to GitHub for version control, diffs, and CI/CD.
239
241
  The agent:
240
242
 
241
243
  - Takes screenshots, inspects UI elements, identifies the app framework
242
- - Loads relevant skills: `get_skill("cdp-browser-automation")` or `get_skill("desktop-uiautomation")`
244
+ - Loads relevant skills: `get_skill("job-build-loop")`, then `get_skill("cdp-browser-automation")` or `get_skill("desktop-uiautomation")`
243
245
  - Checks `list_skills()` for customer-specific skills (e.g., "centricity-quirks")
244
246
  - Studies existing workflows via `get_workflow_overview`
245
247
  - Determines strategy: CDP browser, desktop uiautomation, or hybrid
248
+ - **Writes the test cases before building.** `register_job` (a thin job whose workflow step will call the new workflow) plus `teach_job` or `add_test_case` with a real input and assertions. These cases start red; the rest of the lifecycle exists to turn them green.
246
249
 
247
250
  ### Phase 4: Build (Iterative)
248
251
 
249
252
  For each automation step:
250
253
 
251
- 1. **Observe** `vm_screenshot` + `vm_inspect_ui` to map the UI
252
- 2. **Write** Python script using patterns from loaded skills
253
- 3. **Prototype** `vm_execute_script` to test on the VM directly
254
- 4. **Save** `create_rpa_flow` to persist as a Minicor workflow step
255
- 5. **Test through Minicor** `execute_workflow_async` with `start_from_step`/`end_at_step` to verify the step works through the real executor (config variables, data passing, JS wrapper)
254
+ 1. **Observe** - `vm_screenshot` + `vm_inspect_ui` to map the UI
255
+ 2. **Write** - Python script using patterns from loaded skills
256
+ 3. **Prototype** - `vm_execute_script` to test on the VM directly
257
+ 4. **Save** - `create_rpa_flow` to persist as a Minicor workflow step
258
+ 5. **Test through Minicor** - `execute_workflow_async` with `start_from_step`/`end_at_step` to verify the step works through the real executor (config variables, data passing, JS wrapper)
256
259
 
257
- The testing step is critical `vm_execute_script` doesn't resolve `{{config.*}}` variables or `data.input` interpolation. The agent loads `get_skill("rpa-testing-workflow")` for exact tool call sequences.
260
+ The testing step is critical - `vm_execute_script` doesn't resolve `{{config.*}}` variables or `data.input` interpolation. The agent loads `get_skill("rpa-testing-workflow")` for exact tool call sequences.
258
261
 
259
- ### Phase 5: Test End-to-End
262
+ ### Phase 5: Test End-to-End, Then Green-Gate the Job
260
263
 
261
264
  After all steps pass individually:
262
265
 
263
- - `execute_workflow_async` with real inputs + `configurationId` full workflow, no step isolation
266
+ - `execute_workflow_async` with real inputs + `configurationId` - full workflow, no step isolation
264
267
  - Poll `get_execution_status` + `vm_screenshot` to monitor
265
268
  - `diagnose_execution` on failure, fix with `update_flow`, re-run
266
- - Workflow is NOT done until it passes end-to-end through the Minicor executor
269
+ - The workflow is not done until it passes end-to-end through the Minicor executor
270
+
271
+ Then close the loop at the job level:
272
+
273
+ - Point the job's workflow step at the finished `workflowId` (`update_job variant=draft`). If the workflow was edited in Dev Mode, `dev_mode_publish` first - jobs execute published workflows, not Dev Mode branches.
274
+ - `run_tests variant=draft` - the test cases from Phase 3 are the pass/fail verdict for the build
275
+ - On a red case, `resolve_job_state` / `inspect_job_execution` locate the failing step; replay just that slice with `run_job` (`fromStepId` + `seedExecutionId`) or drop back into the workflow, fix, re-run
276
+ - When the suite is green, `publish_job` puts it live at `/m/:slug/:path`
267
277
 
268
278
  ### Phase 6: Production Hardening
269
279
 
270
280
  For production workflows (not POCs):
271
281
 
272
- - Load `get_skill("state-verification")` add `expectedPreState`/`expectedPostState` to each step
282
+ - Load `get_skill("state-verification")` - add `expectedPreState`/`expectedPostState` to each step
273
283
  - Run the workflow twice to verify idempotency
274
284
  - `create_agent` with `mode: "monitor"` + `watchWorkflowId` for failure monitoring
275
285
  - `create_agent` with `mode: "scheduled"` + cron for recurring runs
@@ -279,50 +289,77 @@ For production workflows (not POCs):
279
289
 
280
290
  After a successful build:
281
291
 
282
- - `generate_skill` gathers workflow code, execution history, and agent issues
292
+ - `generate_skill` - gathers workflow code, execution history, and agent issues
283
293
  - The agent analyzes patterns and calls `save_skill` to persist them
284
294
  - Skills are stored per-workspace and available to future builds
285
295
  - Customer-specific quirks become reusable knowledge
286
296
 
287
297
  ## Jobs (RPA orchestration)
288
298
 
289
- A **Job** is a middleware route whose behavior is a structured `definition` (a step graph) instead of freeform handler code. Jobs sit **above** workflows: a job step either calls an entire Minicor workflow (`kind: "workflow"`, by `workflowId`) or runs a code block (`kind: "code"`). The job never touches a workflow's internal steps a workflow is an opaque callable with an input and an output. A job is the **macro zoom** (what ran, status, replays); a workflow → step is the **microscope**. This is the layer that turns one or more workflows into a versioned, testable, observable API endpoint.
299
+ A **Job** is a middleware route whose behavior is a structured `definition` (a step graph) instead of freeform handler code. Jobs sit **above** workflows: a job step either calls an entire Minicor workflow (`kind: "workflow"`, by `workflowId`) or runs a code block (`kind: "code"`). The job never touches a workflow's internal steps - a workflow is an opaque callable with an input and an output. A job is the **macro zoom** (what ran, status, replays); a workflow → step is the **microscope**. This is the layer that turns one or more workflows into a versioned, testable, observable API endpoint.
290
300
 
291
301
  ### The job tools
292
302
 
293
303
  | Tool | What it does |
294
304
  | --- | --- |
295
- | `list_middlewares` | List the routers (middlewares) in a workspace jobs attach to one of these. |
305
+ | `resolve_job_state` | The first call to make when picking up a job. Returns the job's state (draft vs published, test cases, latest test run, recent executions, active build) plus `nextActions` - the concrete next tool calls. A red test run is drilled automatically: failing case → failing step → its `workflowId` (a `dev_mode_load` hint) a seeded `fromStepId` replay command. |
306
+ | `list_middlewares` | List the routers (middlewares) in a workspace - jobs attach to one of these. |
296
307
  | `register_middleware` | Create a router jobs attach to. `autoConfigure` (default true) populates the router's `workspaceApiKey` from the workspace's first key; or pass `workspaceApiKey` explicitly. |
297
- | `register_job` | Create a job a route backed by a structured `definition` (step graph). |
308
+ | `register_job` | Create a job - a route backed by a structured `definition` (step graph). |
298
309
  | `update_job` | Update a job's `definition`, path, method, or description. `variant: "draft"` writes the draft definition (the teach/build working copy); `variant: "published"` (default) edits the live definition and snapshots a new route version. |
299
310
  | `get_job` | Get a job (route) incl. its `definition` (and `draftDefinition` when one exists); omit `routeId` to list all routes on the router. |
300
- | `run_job` | Run a job once with an input, poll to completion, return the full `JobExecution` (per-step Minicor deep-links). `variant: "draft"` runs the draft definition instead of the published one. |
311
+ | `run_job` | Run a job once with an input, poll to completion, return the full `JobExecution` (per-step Minicor deep-links). `variant: "draft"` runs the draft definition. For step-range debugging, `fromStepId` / `toStepId` (both inclusive) run a slice of the step graph, and `seedExecutionId` hydrates `ctx` from a prior execution so mid-graph starts still resolve earlier steps' values. `waitForResult: false` returns the `jobExecutionId` immediately for runs you want to stop or monitor. |
312
+ | `stop_job_execution` | Stop a queued/running execution. This is a cooperative cancel (there is no pause): a queued run cancels immediately; a running one stops at the runner's next checkpoint (between steps, between `forEach` items, or while waiting on a workflow). A workflow already running on the VM is not killed - it finishes on its own; the job just stops waiting. Idempotent for already-cancelled runs. |
313
+ | `list_job_executions` | List a job's executions (paginated summaries, newest first). Filter by `status` (`queued`/`running`/`succeeded`/`partial`/`failed`/`cancelled`) and/or `trigger` (`test` = suite runs; `api,mcp,cron` = live traffic). Use to find a prior run to seed a range run from, a running execution to stop, or the latest failure to inspect. |
314
+ | `get_job_execution` | Fetch one past execution's full trace: status, input, output, `ctx`, per-step results. |
315
+ | `inspect_job_execution` | Deep-drill an execution end to end: job → steps → (workflow steps) the underlying workflow execution's internal flow-runs, with RPA failure analysis on failures. |
301
316
  | `teach_job` | Teach a job by example: an `input` + a natural-language `prompt` (+ optional `expect` output or refusal, and `artifacts` like Loom links or SOP text). Upserts an idempotent judge-graded test case, folds it into the job's active build run, and, when a draft definition exists, runs the draft now and returns its output + judge verdict. |
302
317
  | `publish_job` | Promote a job's draft definition to published: snapshots a route version, copies draft to published, stamps `publishedAt`. Live traffic serves the new definition immediately. Run `run_tests` with `variant: "draft"` first. |
303
318
  | `get_build_status` | Get a job's build runs (the teach loop's cycles): status `queued`/`running`/`green`/`failed`/`needs_input`, folded-in test cases, builder summary, open questions. Pass `buildId` for one run; omit to list recent runs. |
304
319
  | `answer_build_question` | Answer a `needs_input` question on a build run (credentials choice, ambiguity, 2FA policy). When no open questions remain the build re-queues automatically. |
320
+ | `cancel_build` | Stop a queued/running autonomous build run. The build flips to `failed` with a "stopped by user" summary; the job's draft definition is left as-is. Use it to take the loop over manually. |
305
321
  | `update_build_run` | Builder-facing: update a build run's lifecycle (`running` when you start, `green`/`failed` with a summary when done, `needs_input` with questions when blocked). |
306
322
  | `add_test_case` | Attach a test case to a job: named `input` + assertions (the green-gate). Assertions are `expr` (sandbox boolean) or `judge` (an LLM grades the execution against a natural-language `intent`). |
323
+ | `update_test_case` | Update an existing test case: tighten assertions as behavior firms up, or set `enabled: false` to disable a case without deleting its history. |
307
324
  | `run_tests` | Run a job's test suite (or a subset), poll to completion, return the report (`green`, totals, per-case). `variant: "draft"` runs against the draft definition. |
308
325
  | `get_test_report` | Fetch a test run report by id (totals + per-case results, each linking to its job execution). |
309
- | `list_workspace_api_keys` | List a workspace's API keys (id, apiKey, name) to find a key for the two tools below. |
326
+ | `list_workspace_api_keys` | List a workspace's API keys (id, apiKey, name) - to find a key for the two tools below. |
310
327
  | `set_middleware_api_key` | Set a router's `workspaceApiKey` after the fact, then re-read to confirm it stuck. |
311
328
 
312
- ### The recommended build loop test-driven job workflow
329
+ ### The build loop - test-case-first, macroscopemicroscope
313
330
 
314
- You work **backwards from the job's test cases**. The job's test suite is the macro green-gate; individual workflows are the micro RPA underneath.
331
+ You work **backwards from the job's test cases**. The job's test suite is the macro green-gate; individual workflows are the micro RPA underneath. This mirrors the platform's Jobs UI (Overview = macroscope, Build = microscope). The full playbook ships as the `job-build-loop` skill - load it with `get_skill("job-build-loop")`.
315
332
 
316
333
  ```
317
- 1. CONTRACT FIRST define the JOB's input/output and its test cases (the macro green-gate)
318
- via register_job + add_test_case. Cases start RED.
319
- 2. BUILD WORKFLOWS build/curate the Minicor workflow(s) each step will call (the micro RPA).
320
- 3. WIRE THE STEPS — wire workflows as `kind: "workflow"` steps with `input` mappings,
321
- plus `when` / `forEach` / `cache` / `onError` as needed.
322
- 4. RUN TESTS — run_tests until green: true. (run_job to inspect a single execution.)
334
+ 1. GREEN-GATE FIRST - teach_job (input + intent) or add_test_case (input + assertions).
335
+ A job with no test cases has no definition of correct. Cases start RED.
336
+ 2. BUILD THE DRAFT - register_job / update_job variant=draft. Job steps call PUBLISHED
337
+ Minicor workflows (by workflowId) or run code blocks.
338
+ 3. RUN THE GATE - run_tests variant=draft. Green -> publish_job. Red -> step 4.
339
+ 4. LOCATE (macro) - resolve_job_state tells you where you are and what to do next;
340
+ get_test_report + inspect_job_execution drill a failing case down to
341
+ the failing job step and its workflow's internal flow-runs.
342
+ 5. FIX AT THE RIGHT LEVEL:
343
+ 5a. Job-level - update_job variant=draft, then replay JUST the failing slice:
344
+ run_job variant=draft fromStepId=<failing step>
345
+ seedExecutionId=<failed execution> (seeds ctx so mid-graph starts
346
+ resolve earlier steps' values).
347
+ 5b. Workflow-level (microscope) - the failing step's workflowId -> dev_mode_load,
348
+ fix/run the branch's flow steps with dev_mode_run,
349
+ dev_mode_publish - jobs execute PUBLISHED workflows.
350
+ 6. PUBLISH - when run_tests variant=draft is green, publish_job promotes the draft;
351
+ runtime traffic at /m/:slug serves it immediately.
323
352
  ```
324
353
 
325
- A job step supports `saveAs`, `when` (conditional skip), `forEach` (fan-out), `onError` (`abort`/`skip`/`continue`/`{goto}` `goto` currently treated as abort), `retry`, and `cache` (a login/smart-launch gate). Use `resource.lockKey` to serialize execution per desktop/VM. To migrate an existing NestJS customer middleware onto this layer, use the `nestjs-middleware-to-job` prompt or skill.
354
+ A job step supports `saveAs`, `when` (conditional skip), `forEach` (fan-out), `onError` (`abort`/`skip`/`continue`/`{goto}` - `goto` currently treated as abort), `retry`, and `cache` (a login/smart-launch gate). Use `resource.lockKey` to serialize execution per desktop/VM. To migrate an existing NestJS customer middleware onto this layer, use the `nestjs-middleware-to-job` prompt or skill.
355
+
356
+ ### Execution control - stop, ranges, and traffic lenses
357
+
358
+ - **Stopping:** there is no pause/resume. `stop_job_execution` is a cooperative cancel: a queued run cancels immediately; a running one stops at the runner's next checkpoint (between steps, between `forEach` items, or while waiting on a workflow). A workflow already running on a VM is not killed - it finishes on its own; the job just stops waiting and starts no new steps.
359
+ - **Long or risky runs:** `run_job` with `waitForResult: false` returns the `jobExecutionId` immediately - poll it with `get_job_execution`, stop it with `stop_job_execution`.
360
+ - **Step-range replays:** `run_job` with `fromStepId` / `toStepId` runs only a slice of the step graph (both inclusive, by step id). For any mid-graph start, pass `seedExecutionId` - it hydrates `ctx` from that prior execution so steps you aren't re-running still have their `ctx.*` values. The job's `output` block only runs when the range covers the last step.
361
+ - **Finding runs:** `list_job_executions` returns paginated summaries with `status` and `trigger` filters - `trigger: "test"` isolates suite runs, `trigger: "api,mcp,cron"` isolates live traffic (the same split as the platform's Development/Production lenses).
362
+ - **Autonomous builds:** watch with `get_build_status`, unblock with `answer_build_question`, take over with `cancel_build`. Don't edit the draft while a build is running - coordinate or cancel first.
326
363
 
327
364
  ### Teach-by-example: draft vs published
328
365
 
@@ -351,7 +388,7 @@ The `definition` you pass to `register_job` (see `register_job`'s `definition` p
351
388
 
352
389
  ```ts
353
390
  {
354
- region: "us" | "ca", // region awareness also auto-detected from workspace
391
+ region: "us" | "ca", // region awareness - also auto-detected from workspace
355
392
  resource?: { configStoreId?, lockKey? }, // configStoreId = which VM/desktop; lockKey serializes runs
356
393
  inputSchema: JSONSchema,
357
394
  outputSchema: JSONSchema,
@@ -363,7 +400,7 @@ The `definition` you pass to `register_job` (see `register_job`'s `definition` p
363
400
  }
364
401
  ```
365
402
 
366
- **`ctx` is the data through-line** between steps each step's `saveAs` key is what the next step reads:
403
+ **`ctx` is the data through-line** between steps - each step's `saveAs` key is what the next step reads:
367
404
 
368
405
  - `ctx` starts as `{ input: <the job input> }`.
369
406
  - Each step's result is stored at `ctx.<saveAs>` (when `saveAs` is set), so later steps / `when` / `forEach` / `output` can read it.
@@ -374,7 +411,7 @@ Assertions (`add_test_case`) are either `expr` (TS booleans over `{ input, outpu
374
411
 
375
412
  ### Region & API key
376
413
 
377
- Jobs are **region-aware** (`us` / `ca`) pass `region` or let it be auto-detected from the workspace. Running a job requires the router's `workspaceApiKey` to be set so a job's workflow steps can call the Laminar API: it's populated by `register_middleware`'s `autoConfigure` (default), or set later with `set_middleware_api_key` (find a key via `list_workspace_api_keys`). `register_middleware` / `set_middleware_api_key` report `workspaceApiKeyConfigured` so you can confirm it stuck.
414
+ Jobs are **region-aware** (`us` / `ca`) - pass `region` or let it be auto-detected from the workspace. Running a job requires the router's `workspaceApiKey` to be set so a job's workflow steps can call the Laminar API: it's populated by `register_middleware`'s `autoConfigure` (default), or set later with `set_middleware_api_key` (find a key via `list_workspace_api_keys`). `register_middleware` / `set_middleware_api_key` report `workspaceApiKeyConfigured` so you can confirm it stuck.
378
415
 
379
416
  ## Skills System
380
417
 
@@ -383,6 +420,7 @@ Skills are reusable RPA patterns that accumulate as you build automations. The M
383
420
 
384
421
  | Skill | Purpose |
385
422
  | ---------------------------- | --------------------------------------------------------------------------------- |
423
+ | `job-build-loop` | **Mandatory for job work.** The test-case-first build/debug loop: green-gate first, macroscope (job) → microscope (workflow steps), seeded range replays, stop semantics, publish gates |
386
424
  | `rpa-testing-workflow` | **Mandatory.** Exact tool call sequences for testing through the Minicor executor |
387
425
  | `cdp-browser-automation` | CDP starter template, React-safe setters, parallel execution |
388
426
  | `desktop-uiautomation` | Framework selection, element selectors, wait/retry patterns |
@@ -407,18 +445,18 @@ Skills are automatically persisted through the Minicor platform API. When authen
407
445
 
408
446
  Skill tiers:
409
447
 
410
- - **Global** general RPA knowledge (read-only, bundled with the MCP)
411
- - **Per-workspace** learned from agent sessions, persisted across runs
412
- - **Customer-specific** app quirks, environment patterns
448
+ - **Global** - general RPA knowledge (read-only, bundled with the MCP)
449
+ - **Per-workspace** - learned from agent sessions, persisted across runs
450
+ - **Customer-specific** - app quirks, environment patterns
413
451
 
414
452
  Without authentication, skills fall back to the bundled `.md` files in the package.
415
453
 
416
454
  ## What You Can Automate
417
455
 
418
- - **Web portals** Chrome via CDP. React/Angular SPAs, anti-bot sites, payor portals, EHR web apps.
419
- - **Desktop applications** Windows apps via uiautomation, pywinauto, pyautogui. EMR clients, billing software, legacy systems.
420
- - **APIs** Direct HTTP when the agent discovers usable endpoints behind a portal.
421
- - **Hybrid workflows** Mix browser, desktop, and API steps in one workflow.
456
+ - **Web portals** - Chrome via CDP. React/Angular SPAs, anti-bot sites, payor portals, EHR web apps.
457
+ - **Desktop applications** - Windows apps via uiautomation, pywinauto, pyautogui. EMR clients, billing software, legacy systems.
458
+ - **APIs** - Direct HTTP when the agent discovers usable endpoints behind a portal.
459
+ - **Hybrid workflows** - Mix browser, desktop, and API steps in one workflow.
422
460
 
423
461
  ## VM Setup
424
462
 
@@ -430,7 +468,7 @@ The easiest path is to let the agent handle everything:
430
468
 
431
469
  The agent runs: `deploy_vm` → `install_mds_on_vm` → `start_mds_on_vm` → `vm_connect`
432
470
 
433
- Once the VM is provisioned, a secure tunnel is automatically created. The agent connects via the tunnel URL and is ready to build automations. Chrome instances for browser automation are managed automatically by the MDS no manual setup needed.
471
+ Once the VM is provisioned, a secure tunnel is automatically created. The agent connects via the tunnel URL and is ready to build automations. Chrome instances for browser automation are managed automatically by the MDS - no manual setup needed.
434
472
 
435
473
  For manual setup, use `get_lds_setup_guide` for step-by-step instructions.
436
474
 
@@ -487,25 +525,32 @@ For manual setup, use `get_lds_setup_guide` for step-by-step instructions.
487
525
 
488
526
  | Tool | What it does |
489
527
  | --------------------- | -------------------------------------------------------------------------------------------- |
490
- | `list_middlewares` | List the routers (middlewares) in a workspace jobs attach to one of these |
528
+ | `resolve_job_state` | "Where am I in the build loop?" - job state + `nextActions` (the concrete next tool calls) |
529
+ | `list_middlewares` | List the routers (middlewares) in a workspace - jobs attach to one of these |
491
530
  | `register_middleware` | Create a router (middleware) jobs attach to; `autoConfigure` populates its workspace API key |
492
- | `register_job` | Create a job a middleware route backed by a structured `definition` (step graph) |
531
+ | `register_job` | Create a job - a middleware route backed by a structured `definition` (step graph) |
493
532
  | `update_job` | Update a job's `definition`, path, method, or description; `variant: "draft"` writes the draft |
494
533
  | `get_job` | Get a job (route) incl. its `definition`; omit `routeId` to list all routes on the router |
495
- | `run_job` | Run a job once with an input, poll to completion; `variant: "draft"` runs the draft definition |
534
+ | `run_job` | Run a job once, poll to completion; `variant: "draft"` runs the draft. Step-range replays via `fromStepId`/`toStepId` + `seedExecutionId`; `waitForResult: false` returns the execution id immediately |
535
+ | `stop_job_execution` | Cooperative cancel of a queued/running execution (no pause; VM workflows finish on their own) |
536
+ | `list_job_executions` | Paginated execution summaries with `status`/`trigger` filters (test vs live traffic) |
537
+ | `get_job_execution` | Fetch one execution's full trace (status, input, output, `ctx`, per-step results) |
538
+ | `inspect_job_execution` | Deep-drill: job → steps → workflow execution's internal flow-runs, with RPA failure analysis |
496
539
  | `teach_job` | Teach by example: upsert a judge-graded test case from input + prompt; runs the draft if one exists |
497
540
  | `publish_job` | Promote a job's draft definition to published (snapshots a version); live traffic serves it |
498
541
  | `get_build_status` | Get a job's build runs: status, folded-in test cases, builder summary, open questions |
499
542
  | `answer_build_question` | Answer a `needs_input` question on a build run; the build re-queues when none remain |
543
+ | `cancel_build` | Stop a queued/running autonomous build run (flips to `failed`; the draft is left as-is) |
500
544
  | `update_build_run` | Builder-facing: set a build run's status (`running`/`green`/`failed`/`needs_input`) + summary |
501
545
  | `add_test_case` | Attach a test case to a job: named `input` + `expr` or `judge` assertions (the green-gate) |
546
+ | `update_test_case` | Update a test case (tighten assertions, or `enabled: false` to disable without deleting) |
502
547
  | `run_tests` | Run a job's test suite, poll to completion, return the report; `variant: "draft"` tests the draft |
503
548
  | `get_test_report` | Fetch a test run report by id (totals + per-case results, each linking to its job execution) |
504
- | `list_workspace_api_keys` | List a workspace's API keys (id, apiKey, name) find one for the two tools below |
549
+ | `list_workspace_api_keys` | List a workspace's API keys (id, apiKey, name) - find one for the two tools below |
505
550
  | `set_middleware_api_key` | Set a router's `workspaceApiKey` (then re-reads to confirm it stuck) |
506
551
 
507
552
 
508
- See the **Jobs (RPA orchestration)** section above for the build loop and job/ctx shape. `batch_test_rpa` can also persist each passing input as a real job test case set `persistAsTestCases` with `routeId` + `middlewareId` + `workspaceId`.
553
+ See the **Jobs (RPA orchestration)** section above for the build loop and job/ctx shape. `batch_test_rpa` can also persist each passing input as a real job test case - set `persistAsTestCases` with `routeId` + `middlewareId` + `workspaceId`.
509
554
 
510
555
  ### 2FA / OTP
511
556
 
@@ -541,7 +586,7 @@ Workflows that encounter 2FA prompts use these tools to auto-resolve OTP challen
541
586
  | `update_config_property` / `remove_config_property` | Manage individual properties |
542
587
 
543
588
 
544
- Scripts reference credentials as `{{config.propertyKey}}` resolved at runtime by the workflow engine.
589
+ Scripts reference credentials as `{{config.propertyKey}}` - resolved at runtime by the workflow engine.
545
590
 
546
591
  ### Issues
547
592
 
@@ -557,9 +602,9 @@ Scripts reference credentials as `{{config.propertyKey}}` — resolved at runtim
557
602
 
558
603
  Agents use Issues to persist context across runs with the `[Agent:<name>]` title convention:
559
604
 
560
- - `[Agent:my-bot] Rules` learned behaviors (e.g., "login page takes 15s to load")
561
- - `[Agent:my-bot] Context` persistent state (URLs, credential rotation dates)
562
- - `[Agent:my-bot] Session 2026-04-09` run summaries
605
+ - `[Agent:my-bot] Rules` - learned behaviors (e.g., "login page takes 15s to load")
606
+ - `[Agent:my-bot] Context` - persistent state (URLs, credential rotation dates)
607
+ - `[Agent:my-bot] Session 2026-04-09` - run summaries
563
608
 
564
609
  ### Agents
565
610
 
@@ -622,9 +667,9 @@ Agents are autonomous runners that execute tasks on VMs using MCP tools. After b
622
667
 
623
668
  The `build-rpa-workflow` prompt accepts a `mode` parameter:
624
669
 
625
- - `**poc**` Quick prototype. Streamlined testing, no state verification or monitoring.
626
- - `**production**` Full hardening. State verification, idempotency testing, monitoring agent, context persistence.
627
- - **Omitted** The agent asks the user which mode to use.
670
+ - `**poc**` - Quick prototype. Streamlined testing, no state verification or monitoring.
671
+ - `**production**` - Full hardening. State verification, idempotency testing, monitoring agent, context persistence.
672
+ - **Omitted** - The agent asks the user which mode to use.
628
673
 
629
674
  ## Environment Variables
630
675
 
@@ -664,23 +709,23 @@ npm test
664
709
 
665
710
  ```
666
711
  src/
667
- index.ts CLI MCP entry (stdio transport, token management, disconnect hooks)
668
- lib.ts Embeddable server factory (in-process, no side effects)
669
- bootstrap.ts CLI to generate harness configs (CLAUDE.md, .cursor/rules, etc.)
670
- config.ts User config (~/.minicor/config.json) workspacesRoot, etc.
671
- state.ts Shared mutable state (VM connections, active session tracking)
672
- skills.ts Skill loader, parser, index builder
712
+ index.ts - CLI MCP entry (stdio transport, token management, disconnect hooks)
713
+ lib.ts - Embeddable server factory (in-process, no side effects)
714
+ bootstrap.ts - CLI to generate harness configs (CLAUDE.md, .cursor/rules, etc.)
715
+ config.ts - User config (~/.minicor/config.json) - workspacesRoot, etc.
716
+ state.ts - Shared mutable state (VM connections, active session tracking)
717
+ skills.ts - Skill loader, parser, index builder
673
718
  tools/
674
- session.ts session_start, session_checkpoint, session_end, auto-checkpoint
675
- skills.ts list_skills, get_skill, save_skill, generate_skill
676
- sync-tools.ts clone_workspace, init_project, pull/push, set_workspaces_root
677
- vm.ts, vm-rpa.ts VM and RPA tools
678
- core.ts Workflows, flows, executions
719
+ session.ts - session_start, session_checkpoint, session_end, auto-checkpoint
720
+ skills.ts - list_skills, get_skill, save_skill, generate_skill
721
+ sync-tools.ts - clone_workspace, init_project, pull/push, set_workspaces_root
722
+ vm.ts, vm-rpa.ts - VM and RPA tools
723
+ core.ts - Workflows, flows, executions
679
724
  ...
680
725
  prompts/
681
- workspace-session.ts Workspace session guide prompt
682
- build-rpa.ts Guided RPA building (POC/production modes)
726
+ workspace-session.ts - Workspace session guide prompt
727
+ build-rpa.ts - Guided RPA building (POC/production modes)
683
728
  ...
684
729
  skills/
685
- general/ Bundled skill files (shipped with npm package)
730
+ general/ - Bundled skill files (shipped with npm package)
686
731
  ```