@minicor/mcp-server 2.0.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 (134) hide show
  1. package/README.md +169 -0
  2. package/dist/__tests__/diff.test.d.ts +2 -0
  3. package/dist/__tests__/diff.test.d.ts.map +1 -0
  4. package/dist/__tests__/diff.test.js +23 -0
  5. package/dist/__tests__/diff.test.js.map +1 -0
  6. package/dist/__tests__/helpers.test.d.ts +2 -0
  7. package/dist/__tests__/helpers.test.d.ts.map +1 -0
  8. package/dist/__tests__/helpers.test.js +70 -0
  9. package/dist/__tests__/helpers.test.js.map +1 -0
  10. package/dist/__tests__/inspect-scripts.test.d.ts +2 -0
  11. package/dist/__tests__/inspect-scripts.test.d.ts.map +1 -0
  12. package/dist/__tests__/inspect-scripts.test.js +66 -0
  13. package/dist/__tests__/inspect-scripts.test.js.map +1 -0
  14. package/dist/browser-client.d.ts +42 -0
  15. package/dist/browser-client.d.ts.map +1 -0
  16. package/dist/browser-client.js +66 -0
  17. package/dist/browser-client.js.map +1 -0
  18. package/dist/cli.d.ts +14 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +256 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/config.d.ts +21 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js +57 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/diff.d.ts +7 -0
  27. package/dist/diff.d.ts.map +1 -0
  28. package/dist/diff.js +97 -0
  29. package/dist/diff.js.map +1 -0
  30. package/dist/helpers.d.ts +28 -0
  31. package/dist/helpers.d.ts.map +1 -0
  32. package/dist/helpers.js +91 -0
  33. package/dist/helpers.js.map +1 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +193 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/inspect-scripts.d.ts +18 -0
  39. package/dist/inspect-scripts.d.ts.map +1 -0
  40. package/dist/inspect-scripts.js +572 -0
  41. package/dist/inspect-scripts.js.map +1 -0
  42. package/dist/laminar-client.d.ts +160 -0
  43. package/dist/laminar-client.d.ts.map +1 -0
  44. package/dist/laminar-client.js +237 -0
  45. package/dist/laminar-client.js.map +1 -0
  46. package/dist/lds-client.d.ts +107 -0
  47. package/dist/lds-client.d.ts.map +1 -0
  48. package/dist/lds-client.js +81 -0
  49. package/dist/lds-client.js.map +1 -0
  50. package/dist/paths.d.ts +17 -0
  51. package/dist/paths.d.ts.map +1 -0
  52. package/dist/paths.js +46 -0
  53. package/dist/paths.js.map +1 -0
  54. package/dist/prompts/build-browser-rpa.d.ts +3 -0
  55. package/dist/prompts/build-browser-rpa.d.ts.map +1 -0
  56. package/dist/prompts/build-browser-rpa.js +90 -0
  57. package/dist/prompts/build-browser-rpa.js.map +1 -0
  58. package/dist/prompts/build-rpa.d.ts +3 -0
  59. package/dist/prompts/build-rpa.d.ts.map +1 -0
  60. package/dist/prompts/build-rpa.js +168 -0
  61. package/dist/prompts/build-rpa.js.map +1 -0
  62. package/dist/prompts/debug-execution.d.ts +3 -0
  63. package/dist/prompts/debug-execution.d.ts.map +1 -0
  64. package/dist/prompts/debug-execution.js +50 -0
  65. package/dist/prompts/debug-execution.js.map +1 -0
  66. package/dist/prompts/workflow-guide.d.ts +3 -0
  67. package/dist/prompts/workflow-guide.d.ts.map +1 -0
  68. package/dist/prompts/workflow-guide.js +175 -0
  69. package/dist/prompts/workflow-guide.js.map +1 -0
  70. package/dist/services.d.ts +61 -0
  71. package/dist/services.d.ts.map +1 -0
  72. package/dist/services.js +249 -0
  73. package/dist/services.js.map +1 -0
  74. package/dist/setup.d.ts +11 -0
  75. package/dist/setup.d.ts.map +1 -0
  76. package/dist/setup.js +790 -0
  77. package/dist/setup.js.map +1 -0
  78. package/dist/state.d.ts +23 -0
  79. package/dist/state.d.ts.map +1 -0
  80. package/dist/state.js +24 -0
  81. package/dist/state.js.map +1 -0
  82. package/dist/sync.d.ts +86 -0
  83. package/dist/sync.d.ts.map +1 -0
  84. package/dist/sync.js +394 -0
  85. package/dist/sync.js.map +1 -0
  86. package/dist/tools/browser.d.ts +3 -0
  87. package/dist/tools/browser.d.ts.map +1 -0
  88. package/dist/tools/browser.js +254 -0
  89. package/dist/tools/browser.js.map +1 -0
  90. package/dist/tools/config-stores.d.ts +3 -0
  91. package/dist/tools/config-stores.d.ts.map +1 -0
  92. package/dist/tools/config-stores.js +54 -0
  93. package/dist/tools/config-stores.js.map +1 -0
  94. package/dist/tools/core.d.ts +3 -0
  95. package/dist/tools/core.d.ts.map +1 -0
  96. package/dist/tools/core.js +202 -0
  97. package/dist/tools/core.js.map +1 -0
  98. package/dist/tools/cron.d.ts +3 -0
  99. package/dist/tools/cron.d.ts.map +1 -0
  100. package/dist/tools/cron.js +168 -0
  101. package/dist/tools/cron.js.map +1 -0
  102. package/dist/tools/elasticsearch.d.ts +3 -0
  103. package/dist/tools/elasticsearch.d.ts.map +1 -0
  104. package/dist/tools/elasticsearch.js +248 -0
  105. package/dist/tools/elasticsearch.js.map +1 -0
  106. package/dist/tools/issues.d.ts +3 -0
  107. package/dist/tools/issues.d.ts.map +1 -0
  108. package/dist/tools/issues.js +39 -0
  109. package/dist/tools/issues.js.map +1 -0
  110. package/dist/tools/stats.d.ts +3 -0
  111. package/dist/tools/stats.d.ts.map +1 -0
  112. package/dist/tools/stats.js +18 -0
  113. package/dist/tools/stats.js.map +1 -0
  114. package/dist/tools/sync-tools.d.ts +3 -0
  115. package/dist/tools/sync-tools.d.ts.map +1 -0
  116. package/dist/tools/sync-tools.js +121 -0
  117. package/dist/tools/sync-tools.js.map +1 -0
  118. package/dist/tools/vm-rpa.d.ts +3 -0
  119. package/dist/tools/vm-rpa.d.ts.map +1 -0
  120. package/dist/tools/vm-rpa.js +281 -0
  121. package/dist/tools/vm-rpa.js.map +1 -0
  122. package/dist/tools/vm.d.ts +3 -0
  123. package/dist/tools/vm.d.ts.map +1 -0
  124. package/dist/tools/vm.js +280 -0
  125. package/dist/tools/vm.js.map +1 -0
  126. package/dist/tools/workflow-ops.d.ts +3 -0
  127. package/dist/tools/workflow-ops.d.ts.map +1 -0
  128. package/dist/tools/workflow-ops.js +313 -0
  129. package/dist/tools/workflow-ops.js.map +1 -0
  130. package/dist/types.d.ts +14 -0
  131. package/dist/types.d.ts.map +1 -0
  132. package/dist/types.js +5 -0
  133. package/dist/types.js.map +1 -0
  134. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # Minicor MCP Server
2
+
3
+ > Formerly known as Laminar
4
+
5
+ Desktop and browser RPA automation, workflow management, and AI-powered debugging for the Minicor platform -- all from **Cursor** or **Claude Code**.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g @minicor/mcp-server
11
+ minicor-mcp-setup
12
+ ```
13
+
14
+ This opens a browser where you can **sign in** or **create an account**, set up workspaces, and optionally configure advanced services (Elasticsearch, CRON). Tokens are stored at `~/.minicor/tokens.json` and auto-refresh.
15
+
16
+ For headless environments:
17
+
18
+ ```bash
19
+ minicor-mcp-setup --cli
20
+ ```
21
+
22
+ Restart Cursor to activate.
23
+
24
+ ## How It Works
25
+
26
+ The setup writes this to `~/.cursor/mcp.json`:
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "minicor": {
32
+ "command": "node",
33
+ "args": ["/path/to/dist/index.js"]
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ No API keys needed -- authentication is handled by your stored session token.
40
+
41
+ ### Claude Code
42
+
43
+ ```bash
44
+ claude mcp add minicor node /absolute/path/to/mcp/dist/index.js
45
+ ```
46
+
47
+ ## Features
48
+
49
+ - **Workspaces** -- list, inspect, manage workspace members
50
+ - **Workflows** -- create, update, clone, delete, restore workflows
51
+ - **Flows (Steps)** -- read/write individual steps, view version history, bulk update
52
+ - **Executions** -- list, search, filter by date/status, inspect full payloads, view per-step results
53
+ - **Execute** -- trigger workflows synchronously or async, poll for status
54
+ - **Configuration Stores** -- manage key-value configs used by `{{config.xxx}}` references
55
+ - **Issues** -- create and manage workspace issues
56
+ - **Desktop RPA** -- connect to a VM, take screenshots, inspect UI, run scripts, build RPA workflows iteratively
57
+ - **Browser RPA** -- session-based browser automation with natural-language actions
58
+ - **RPA Debugging** -- before/after screenshots, batch testing, state reset, execution diagnosis
59
+ - **Log Search** _(advanced)_ -- full-text Elasticsearch search across execution logs
60
+ - **Incident Investigation** -- correlate failures across workflows with timeline analysis
61
+ - **CRON Management** _(advanced)_ -- scheduled job management
62
+ - **Workflow File Sync** -- pull/push workflows to local files for git version control
63
+
64
+ ## Desktop RPA
65
+
66
+ Connect to a VM running the Laminar Desktop Service (LDS) and iteratively build RPA workflows.
67
+
68
+ ### Setup LDS on a VM
69
+
70
+ Use the `get_lds_setup_guide` tool for step-by-step instructions, or:
71
+
72
+ 1. Install LDS on the target Windows VM
73
+ 2. Start it on port 1016
74
+ 3. Expose via Cloudflare Tunnel: `cloudflared tunnel --url http://localhost:1016`
75
+ 4. In Cursor: `vm_connect` with the tunnel URL
76
+
77
+ ### RPA Tools
78
+
79
+ | Tool | Description |
80
+ |---|---|
81
+ | `vm_connect` | Connect to LDS via Cloudflare Tunnel URL |
82
+ | `vm_screenshot` | Capture VM desktop screenshot |
83
+ | `vm_inspect_ui` | Inspect UI elements (accessibility tree, element at point, etc.) |
84
+ | `vm_execute_script` | Run Python script on the VM |
85
+ | `create_rpa_flow` | Save validated Python script as an RPA step (auto-wraps in correct format) |
86
+ | `vm_read_clipboard` | Read clipboard text after copy operations |
87
+ | `vm_screenshot_region` | Crop and zoom a specific screen region |
88
+ | `debug_rpa_step` | Run script with before/after screenshots |
89
+ | `vm_reset_state` | Smart Launch -- reset app to known state |
90
+ | `batch_test_rpa` | Run workflow with multiple test inputs |
91
+ | `get_lds_setup_guide` | Full LDS installation walkthrough |
92
+
93
+ ## Browser RPA
94
+
95
+ Session-based browser automation for web applications.
96
+
97
+ | Tool | Description |
98
+ |---|---|
99
+ | `browser_connect` | Connect to browser RPA service |
100
+ | `browser_create_session` | Start a new browser session |
101
+ | `browser_act` | Natural-language browser actions |
102
+ | `browser_extract` | Extract data from the current page |
103
+ | `browser_screenshot` | Screenshot the browser |
104
+ | `browser_close_session` | Clean up session |
105
+ | `create_browser_rpa_flow` | Save browser action as a workflow step |
106
+
107
+ ## Workflow Tools
108
+
109
+ | Tool | Description |
110
+ |---|---|
111
+ | `preview_flow_changes` | Diff current vs proposed code before pushing |
112
+ | `get_workflow_overview` | Full workflow snapshot with code + executions |
113
+ | `test_workflow_step` | Run up to / from / only a specific step |
114
+ | `diagnose_execution` | Find failures with RPA-specific error analysis |
115
+ | `compare_flow_versions` | Diff between two step versions |
116
+
117
+ ## Advanced Setup
118
+
119
+ Elasticsearch (log search) and CRON (scheduling) are configured during `minicor-mcp-setup` under Advanced Settings, or via `~/.minicor/config.json`:
120
+
121
+ ```json
122
+ {
123
+ "elasticsearch": {
124
+ "endpoint": "https://your-es-cluster.cloud.io",
125
+ "apiKey": "your-es-api-key"
126
+ },
127
+ "cron": {
128
+ "apiKey": "your-cron-api-key"
129
+ }
130
+ }
131
+ ```
132
+
133
+ ## Auth
134
+
135
+ Authentication uses stored session tokens only. No API keys.
136
+
137
+ - **Sign in / sign up**: `minicor-mcp-setup` (browser) or `minicor-mcp-setup --cli`
138
+ - **Token storage**: `~/.minicor/tokens.json` (falls back to `~/.laminar/tokens.json` for existing users)
139
+ - **Auto-refresh**: tokens refresh automatically before expiry
140
+ - **Region**: US (default) or Canada, selected during setup
141
+
142
+ ## Development
143
+
144
+ ```bash
145
+ npm install
146
+ npm run build
147
+ npm test
148
+ npm run dev # watch mode
149
+ npm run test:watch # test watch mode
150
+ ```
151
+
152
+ ### Project Structure
153
+
154
+ ```
155
+ src/
156
+ index.ts -- server orchestrator (auth, init, registration)
157
+ helpers.ts -- shared response helpers (ok, text, safe, buildRpaProgram)
158
+ state.ts -- session state (VM + browser connections)
159
+ paths.ts -- token/config path resolution with ~/.minicor/ + ~/.laminar/ fallback
160
+ types.ts -- shared ToolDeps interface
161
+ setup.ts -- interactive setup (browser + CLI modes)
162
+ tools/ -- tool modules (each exports register())
163
+ prompts/ -- prompt modules (each exports register())
164
+ __tests__/ -- vitest unit tests
165
+ ```
166
+
167
+ ## License
168
+
169
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=diff.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/diff.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { computeDiff } from "../diff.js";
3
+ describe("computeDiff", () => {
4
+ it("shows no changes for identical strings", () => {
5
+ const diff = computeDiff("hello\nworld", "hello\nworld", "A", "B");
6
+ expect(diff).not.toContain("+");
7
+ expect(diff).not.toContain("-");
8
+ });
9
+ it("shows additions", () => {
10
+ const diff = computeDiff("line1", "line1\nline2", "A", "B");
11
+ expect(diff).toContain("+ line2");
12
+ });
13
+ it("shows removals", () => {
14
+ const diff = computeDiff("line1\nline2", "line1", "A", "B");
15
+ expect(diff).toContain("- line2");
16
+ });
17
+ it("uses provided labels", () => {
18
+ const diff = computeDiff("a", "b", "Old", "New");
19
+ expect(diff).toContain("Old");
20
+ expect(diff).toContain("New");
21
+ });
22
+ });
23
+ //# sourceMappingURL=diff.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.test.js","sourceRoot":"","sources":["../../src/__tests__/diff.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACzB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;QACxB,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=helpers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/helpers.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { json, ok, text, safe, buildRpaProgram } from "../helpers.js";
3
+ describe("json", () => {
4
+ it("serializes objects with 2-space indent", () => {
5
+ expect(json({ a: 1 })).toBe('{\n "a": 1\n}');
6
+ });
7
+ it("handles null", () => {
8
+ expect(json(null)).toBe("null");
9
+ });
10
+ });
11
+ describe("ok", () => {
12
+ it("wraps data in MCP text content", () => {
13
+ const result = ok({ foo: "bar" });
14
+ expect(result.content).toHaveLength(1);
15
+ expect(result.content[0].type).toBe("text");
16
+ expect(JSON.parse(result.content[0].text)).toEqual({ foo: "bar" });
17
+ });
18
+ });
19
+ describe("text", () => {
20
+ it("wraps a string in MCP text content", () => {
21
+ const result = text("hello");
22
+ expect(result.content).toHaveLength(1);
23
+ expect(result.content[0].type).toBe("text");
24
+ expect(result.content[0].text).toBe("hello");
25
+ });
26
+ });
27
+ describe("safe", () => {
28
+ it("returns ok() on success", async () => {
29
+ const result = await safe(async () => ({ x: 1 }));
30
+ expect(JSON.parse(result.content[0].text)).toEqual({ x: 1 });
31
+ });
32
+ it("returns text() with error message on failure", async () => {
33
+ const result = await safe(async () => {
34
+ throw new Error("boom");
35
+ });
36
+ expect(result.content[0].text).toBe("Error: boom");
37
+ });
38
+ });
39
+ describe("buildRpaProgram", () => {
40
+ it("generates cloudflare_tunnel pattern with lam.httpRequest", () => {
41
+ const program = buildRpaProgram('print("hello")', "cloudflare_tunnel", "test-step", "Test Step", "A test step");
42
+ expect(program).toContain("lam.httpRequest");
43
+ expect(program).toContain("{{config.laminar_desktop_service_url}}/execute");
44
+ expect(program).toContain("{{config.laminar_desktop_service_api_key}}");
45
+ expect(program).toContain("{{config.laminar_desktop_service_id}}");
46
+ expect(program).toContain('"flowId": "test-step"');
47
+ expect(program).toContain('print("hello")');
48
+ expect(program).toMatch(/^\(data\) =>/);
49
+ });
50
+ it("generates channel pattern with lam.rpa", () => {
51
+ const program = buildRpaProgram('print("hello")', "channel", "test-step", "Test Step", "A test step");
52
+ expect(program).toContain("lam.rpa");
53
+ expect(program).toContain("{{config.channelId}}");
54
+ expect(program).not.toContain("lam.httpRequest");
55
+ expect(program).toMatch(/^\(data\) =>/);
56
+ });
57
+ it("escapes backticks and dollar signs in python script", () => {
58
+ const program = buildRpaProgram('f"value is ${x}" + `tick`', "cloudflare_tunnel", "id", "name", "desc");
59
+ expect(program).toContain("\\`");
60
+ expect(program).toContain("\\$");
61
+ // The escaped form \${x} should be present, not raw ${x}
62
+ expect(program).toContain("\\${x}");
63
+ });
64
+ it("escapes double quotes in step name and description", () => {
65
+ const program = buildRpaProgram("pass", "cloudflare_tunnel", "id", 'Step "with" quotes', 'Desc "here"');
66
+ expect(program).toContain('Step \\"with\\" quotes');
67
+ expect(program).toContain('Desc \\"here\\"');
68
+ });
69
+ });
70
+ //# sourceMappingURL=helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.test.js","sourceRoot":"","sources":["../../src/__tests__/helpers.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=inspect-scripts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-scripts.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inspect-scripts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { generateInspectScript } from "../inspect-scripts.js";
3
+ describe("generateInspectScript", () => {
4
+ describe("uiautomation (auto)", () => {
5
+ it("generates window_list script", () => {
6
+ const script = generateInspectScript({ mode: "window_list" });
7
+ expect(script).toContain("import json, uiautomation as auto");
8
+ expect(script).toContain("GetRootControl");
9
+ expect(script).toContain("print(json.dumps");
10
+ });
11
+ it("generates screen_info script", () => {
12
+ const script = generateInspectScript({ mode: "screen_info" });
13
+ expect(script).toContain("GetSystemMetrics");
14
+ expect(script).toContain("screenWidth");
15
+ });
16
+ it("generates element_at_point script with coordinates", () => {
17
+ const script = generateInspectScript({
18
+ mode: "element_at_point",
19
+ x: 100,
20
+ y: 200,
21
+ });
22
+ expect(script).toContain("x, y = 100, 200");
23
+ expect(script).toContain("ControlFromPoint");
24
+ });
25
+ it("generates element_tree script with depth", () => {
26
+ const script = generateInspectScript({
27
+ mode: "element_tree",
28
+ depth: 5,
29
+ });
30
+ expect(script).toContain("MAX_DEPTH = 5");
31
+ expect(script).toContain("build_tree");
32
+ });
33
+ it("generates element_tree script with window title", () => {
34
+ const script = generateInspectScript({
35
+ mode: "element_tree",
36
+ windowTitle: "Open Dental",
37
+ });
38
+ expect(script).toContain('"Open Dental"');
39
+ expect(script).toContain("WindowControl");
40
+ });
41
+ it("generates focused_element script", () => {
42
+ const script = generateInspectScript({ mode: "focused_element" });
43
+ expect(script).toContain("GetFocusedControl");
44
+ });
45
+ });
46
+ describe("pywinauto", () => {
47
+ it("generates window_list script", () => {
48
+ const script = generateInspectScript({
49
+ mode: "window_list",
50
+ framework: "pywinauto",
51
+ });
52
+ expect(script).toContain("from pywinauto import Desktop");
53
+ expect(script).toContain('backend="uia"');
54
+ });
55
+ });
56
+ describe("jab", () => {
57
+ it("generates window_list script", () => {
58
+ const script = generateInspectScript({
59
+ mode: "window_list",
60
+ framework: "jab",
61
+ });
62
+ expect(script).toContain("JavaAccessBridgeWrapper");
63
+ });
64
+ });
65
+ });
66
+ //# sourceMappingURL=inspect-scripts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-scripts.test.js","sourceRoot":"","sources":["../../src/__tests__/inspect-scripts.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Stateless HTTP client for Browser RPA sessions.
3
+ *
4
+ * Matches the session-based API pattern from Sully QA workspace:
5
+ * POST /sessions → create session
6
+ * POST /sessions/:id/act → send action
7
+ * POST /sessions/:id/extract → extract data
8
+ * GET /sessions/:id/screenshot → screenshot
9
+ * DELETE /sessions/:id → close session
10
+ */
11
+ export interface BrowserAuth {
12
+ bearerToken: string;
13
+ }
14
+ export interface BrowserSessionResponse {
15
+ sessionId: string;
16
+ [key: string]: unknown;
17
+ }
18
+ export interface BrowserActResponse {
19
+ success?: boolean;
20
+ result?: unknown;
21
+ [key: string]: unknown;
22
+ }
23
+ export interface BrowserExtractResponse {
24
+ success?: boolean;
25
+ data?: unknown;
26
+ [key: string]: unknown;
27
+ }
28
+ export interface BrowserScreenshotResponse {
29
+ image?: string;
30
+ screenshot?: string;
31
+ [key: string]: unknown;
32
+ }
33
+ export declare function createSession(baseUrl: string, auth: BrowserAuth, opts?: {
34
+ slackChannelId?: string;
35
+ }): Promise<BrowserSessionResponse>;
36
+ export declare function act(baseUrl: string, sessionId: string, message: string, auth: BrowserAuth): Promise<BrowserActResponse>;
37
+ export declare function extract(baseUrl: string, sessionId: string, instructions: string, auth: BrowserAuth): Promise<BrowserExtractResponse>;
38
+ export declare function screenshot(baseUrl: string, sessionId: string, auth: BrowserAuth): Promise<BrowserScreenshotResponse>;
39
+ export declare function closeSession(baseUrl: string, sessionId: string, auth: BrowserAuth): Promise<{
40
+ closed: boolean;
41
+ }>;
42
+ //# sourceMappingURL=browser-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-client.d.ts","sourceRoot":"","sources":["../src/browser-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAwBD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,EACjB,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GACjC,OAAO,CAAC,sBAAsB,CAAC,CAOjC;AAED,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAO7B;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAOjC;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,yBAAyB,CAAC,CAKpC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,CAO9B"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Stateless HTTP client for Browser RPA sessions.
3
+ *
4
+ * Matches the session-based API pattern from Sully QA workspace:
5
+ * POST /sessions → create session
6
+ * POST /sessions/:id/act → send action
7
+ * POST /sessions/:id/extract → extract data
8
+ * GET /sessions/:id/screenshot → screenshot
9
+ * DELETE /sessions/:id → close session
10
+ */
11
+ function normalizeUrl(base) {
12
+ return base.replace(/\/+$/, "");
13
+ }
14
+ function authHeaders(auth) {
15
+ return {
16
+ "Authorization": `Bearer ${auth.bearerToken}`,
17
+ "Content-Type": "application/json",
18
+ };
19
+ }
20
+ async function request(url, init) {
21
+ const res = await fetch(url, init);
22
+ if (!res.ok) {
23
+ const body = await res.text().catch(() => "");
24
+ throw new Error(`Browser RPA ${init?.method ?? "GET"} ${url} returned ${res.status}: ${body}`);
25
+ }
26
+ return res.json();
27
+ }
28
+ export async function createSession(baseUrl, auth, opts) {
29
+ const url = `${normalizeUrl(baseUrl)}/sessions`;
30
+ return request(url, {
31
+ method: "POST",
32
+ headers: authHeaders(auth),
33
+ body: JSON.stringify(opts?.slackChannelId ? { slackChannelId: opts.slackChannelId } : {}),
34
+ });
35
+ }
36
+ export async function act(baseUrl, sessionId, message, auth) {
37
+ const url = `${normalizeUrl(baseUrl)}/sessions/${sessionId}/act`;
38
+ return request(url, {
39
+ method: "POST",
40
+ headers: authHeaders(auth),
41
+ body: JSON.stringify({ message }),
42
+ });
43
+ }
44
+ export async function extract(baseUrl, sessionId, instructions, auth) {
45
+ const url = `${normalizeUrl(baseUrl)}/sessions/${sessionId}/extract`;
46
+ return request(url, {
47
+ method: "POST",
48
+ headers: authHeaders(auth),
49
+ body: JSON.stringify({ instructions }),
50
+ });
51
+ }
52
+ export async function screenshot(baseUrl, sessionId, auth) {
53
+ const url = `${normalizeUrl(baseUrl)}/sessions/${sessionId}/screenshot`;
54
+ return request(url, {
55
+ headers: { "Authorization": `Bearer ${auth.bearerToken}` },
56
+ });
57
+ }
58
+ export async function closeSession(baseUrl, sessionId, auth) {
59
+ const url = `${normalizeUrl(baseUrl)}/sessions/${sessionId}`;
60
+ await request(url, {
61
+ method: "DELETE",
62
+ headers: { "Authorization": `Bearer ${auth.bearerToken}` },
63
+ });
64
+ return { closed: true };
65
+ }
66
+ //# sourceMappingURL=browser-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-client.js","sourceRoot":"","sources":["../src/browser-client.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Laminar CLI — manage workflows from the terminal or CI/CD pipelines.
4
+ *
5
+ * Usage:
6
+ * laminar init --workspace <id> [--output <dir>]
7
+ * laminar pull [--all | --workflow <id> --output <dir>]
8
+ * laminar push [--changed | --workflow <dir>]
9
+ * laminar diff [--all | --workflow <dir>]
10
+ *
11
+ * Auth: Set LAMINAR_API_KEY env var, or run `laminar-mcp-setup` first.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}