@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.
- package/README.md +169 -0
- package/dist/__tests__/diff.test.d.ts +2 -0
- package/dist/__tests__/diff.test.d.ts.map +1 -0
- package/dist/__tests__/diff.test.js +23 -0
- package/dist/__tests__/diff.test.js.map +1 -0
- package/dist/__tests__/helpers.test.d.ts +2 -0
- package/dist/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/__tests__/helpers.test.js +70 -0
- package/dist/__tests__/helpers.test.js.map +1 -0
- package/dist/__tests__/inspect-scripts.test.d.ts +2 -0
- package/dist/__tests__/inspect-scripts.test.d.ts.map +1 -0
- package/dist/__tests__/inspect-scripts.test.js +66 -0
- package/dist/__tests__/inspect-scripts.test.js.map +1 -0
- package/dist/browser-client.d.ts +42 -0
- package/dist/browser-client.d.ts.map +1 -0
- package/dist/browser-client.js +66 -0
- package/dist/browser-client.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +256 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/diff.d.ts +7 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +97 -0
- package/dist/diff.js.map +1 -0
- package/dist/helpers.d.ts +28 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +91 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-scripts.d.ts +18 -0
- package/dist/inspect-scripts.d.ts.map +1 -0
- package/dist/inspect-scripts.js +572 -0
- package/dist/inspect-scripts.js.map +1 -0
- package/dist/laminar-client.d.ts +160 -0
- package/dist/laminar-client.d.ts.map +1 -0
- package/dist/laminar-client.js +237 -0
- package/dist/laminar-client.js.map +1 -0
- package/dist/lds-client.d.ts +107 -0
- package/dist/lds-client.d.ts.map +1 -0
- package/dist/lds-client.js +81 -0
- package/dist/lds-client.js.map +1 -0
- package/dist/paths.d.ts +17 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +46 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts/build-browser-rpa.d.ts +3 -0
- package/dist/prompts/build-browser-rpa.d.ts.map +1 -0
- package/dist/prompts/build-browser-rpa.js +90 -0
- package/dist/prompts/build-browser-rpa.js.map +1 -0
- package/dist/prompts/build-rpa.d.ts +3 -0
- package/dist/prompts/build-rpa.d.ts.map +1 -0
- package/dist/prompts/build-rpa.js +168 -0
- package/dist/prompts/build-rpa.js.map +1 -0
- package/dist/prompts/debug-execution.d.ts +3 -0
- package/dist/prompts/debug-execution.d.ts.map +1 -0
- package/dist/prompts/debug-execution.js +50 -0
- package/dist/prompts/debug-execution.js.map +1 -0
- package/dist/prompts/workflow-guide.d.ts +3 -0
- package/dist/prompts/workflow-guide.d.ts.map +1 -0
- package/dist/prompts/workflow-guide.js +175 -0
- package/dist/prompts/workflow-guide.js.map +1 -0
- package/dist/services.d.ts +61 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +249 -0
- package/dist/services.js.map +1 -0
- package/dist/setup.d.ts +11 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +790 -0
- package/dist/setup.js.map +1 -0
- package/dist/state.d.ts +23 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +24 -0
- package/dist/state.js.map +1 -0
- package/dist/sync.d.ts +86 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +394 -0
- package/dist/sync.js.map +1 -0
- package/dist/tools/browser.d.ts +3 -0
- package/dist/tools/browser.d.ts.map +1 -0
- package/dist/tools/browser.js +254 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/config-stores.d.ts +3 -0
- package/dist/tools/config-stores.d.ts.map +1 -0
- package/dist/tools/config-stores.js +54 -0
- package/dist/tools/config-stores.js.map +1 -0
- package/dist/tools/core.d.ts +3 -0
- package/dist/tools/core.d.ts.map +1 -0
- package/dist/tools/core.js +202 -0
- package/dist/tools/core.js.map +1 -0
- package/dist/tools/cron.d.ts +3 -0
- package/dist/tools/cron.d.ts.map +1 -0
- package/dist/tools/cron.js +168 -0
- package/dist/tools/cron.js.map +1 -0
- package/dist/tools/elasticsearch.d.ts +3 -0
- package/dist/tools/elasticsearch.d.ts.map +1 -0
- package/dist/tools/elasticsearch.js +248 -0
- package/dist/tools/elasticsearch.js.map +1 -0
- package/dist/tools/issues.d.ts +3 -0
- package/dist/tools/issues.d.ts.map +1 -0
- package/dist/tools/issues.js +39 -0
- package/dist/tools/issues.js.map +1 -0
- package/dist/tools/stats.d.ts +3 -0
- package/dist/tools/stats.d.ts.map +1 -0
- package/dist/tools/stats.js +18 -0
- package/dist/tools/stats.js.map +1 -0
- package/dist/tools/sync-tools.d.ts +3 -0
- package/dist/tools/sync-tools.d.ts.map +1 -0
- package/dist/tools/sync-tools.js +121 -0
- package/dist/tools/sync-tools.js.map +1 -0
- package/dist/tools/vm-rpa.d.ts +3 -0
- package/dist/tools/vm-rpa.d.ts.map +1 -0
- package/dist/tools/vm-rpa.js +281 -0
- package/dist/tools/vm-rpa.js.map +1 -0
- package/dist/tools/vm.d.ts +3 -0
- package/dist/tools/vm.d.ts.map +1 -0
- package/dist/tools/vm.js +280 -0
- package/dist/tools/vm.js.map +1 -0
- package/dist/tools/workflow-ops.d.ts +3 -0
- package/dist/tools/workflow-ops.d.ts.map +1 -0
- package/dist/tools/workflow-ops.js +313 -0
- package/dist/tools/workflow-ops.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/dist/paths.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path resolution for token and config storage.
|
|
3
|
+
*
|
|
4
|
+
* New installs write to ~/.minicor/. Existing ~/.laminar/ installs
|
|
5
|
+
* keep working via fallback reads. Once a user re-auths, tokens
|
|
6
|
+
* silently migrate to ~/.minicor/.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import os from "node:os";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
const MINICOR_DIR = path.join(os.homedir(), ".minicor");
|
|
12
|
+
const LEGACY_DIR = path.join(os.homedir(), ".laminar");
|
|
13
|
+
export { MINICOR_DIR };
|
|
14
|
+
export function getTokenPath() {
|
|
15
|
+
const minicorPath = path.join(MINICOR_DIR, "tokens.json");
|
|
16
|
+
if (fs.existsSync(minicorPath))
|
|
17
|
+
return minicorPath;
|
|
18
|
+
const legacyPath = path.join(LEGACY_DIR, "tokens.json");
|
|
19
|
+
if (fs.existsSync(legacyPath))
|
|
20
|
+
return legacyPath;
|
|
21
|
+
return minicorPath;
|
|
22
|
+
}
|
|
23
|
+
export function getWriteTokenPath() {
|
|
24
|
+
return path.join(MINICOR_DIR, "tokens.json");
|
|
25
|
+
}
|
|
26
|
+
export function getConfigPath() {
|
|
27
|
+
const minicorPath = path.join(MINICOR_DIR, "config.json");
|
|
28
|
+
if (fs.existsSync(minicorPath))
|
|
29
|
+
return minicorPath;
|
|
30
|
+
const legacyPath = path.join(LEGACY_DIR, "config.json");
|
|
31
|
+
if (fs.existsSync(legacyPath))
|
|
32
|
+
return legacyPath;
|
|
33
|
+
return minicorPath;
|
|
34
|
+
}
|
|
35
|
+
export function getWriteConfigPath() {
|
|
36
|
+
return path.join(MINICOR_DIR, "config.json");
|
|
37
|
+
}
|
|
38
|
+
export function regionToApiBase(region) {
|
|
39
|
+
return region === "ca"
|
|
40
|
+
? "https://ca.api.laminar.run"
|
|
41
|
+
: "https://api.laminar.run";
|
|
42
|
+
}
|
|
43
|
+
export function apiBaseToRegion(apiBase) {
|
|
44
|
+
return apiBase.includes("ca.api") ? "ca" : "us";
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACxD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,UAAU,YAAY;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACjD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACjD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAID,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,KAAK,IAAI;QACpB,CAAC,CAAC,4BAA4B;QAC9B,CAAC,CAAC,yBAAyB,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-browser-rpa.d.ts","sourceRoot":"","sources":["../../src/prompts/build-browser-rpa.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QA8F5C"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register({ server }) {
|
|
3
|
+
server.prompt("build-browser-rpa-workflow", "Iteratively build a browser-based RPA workflow using the Laminar Browser RPA service. Guides you through creating a browser session, performing actions, extracting data, and saving each step as a Laminar workflow flow.", {
|
|
4
|
+
workspaceId: z.string().describe("Laminar workspace ID"),
|
|
5
|
+
task: z
|
|
6
|
+
.string()
|
|
7
|
+
.describe("Description of what to automate (e.g. 'Log into athenaHealth, navigate to patient chart, extract insurance info')"),
|
|
8
|
+
targetUrl: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Starting URL for the web application"),
|
|
11
|
+
workflowId: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Existing workflow ID to add steps to (omit to create a new workflow)"),
|
|
15
|
+
}, async ({ workspaceId, task, targetUrl, workflowId }) => ({
|
|
16
|
+
messages: [
|
|
17
|
+
{
|
|
18
|
+
role: "user",
|
|
19
|
+
content: {
|
|
20
|
+
type: "text",
|
|
21
|
+
text: `You are building a browser-based RPA workflow on the Laminar platform. Your goal is to automate web application interactions using the Browser RPA session API.
|
|
22
|
+
|
|
23
|
+
## Task
|
|
24
|
+
${task}
|
|
25
|
+
|
|
26
|
+
## Target URL
|
|
27
|
+
${targetUrl}
|
|
28
|
+
|
|
29
|
+
## Workspace
|
|
30
|
+
ID: ${workspaceId}${workflowId ? `\nExisting workflow ID: ${workflowId} (add steps to this workflow)` : "\nCreate a new workflow for this automation."}
|
|
31
|
+
|
|
32
|
+
## How Browser RPA Works
|
|
33
|
+
|
|
34
|
+
The Browser RPA service provides a session-based API:
|
|
35
|
+
1. **Create Session** — starts a browser instance, returns a sessionId
|
|
36
|
+
2. **Act** — sends natural-language actions (e.g. "click the login button", "type hello@example.com in the email field")
|
|
37
|
+
3. **Extract** — extracts data from the current page via natural-language instructions
|
|
38
|
+
4. **Screenshot** — captures the current browser state
|
|
39
|
+
5. **Close Session** — cleans up
|
|
40
|
+
|
|
41
|
+
## Procedure
|
|
42
|
+
|
|
43
|
+
### 1. Connect to Browser RPA Service
|
|
44
|
+
Call \`browser_connect\` with the service base URL and bearer token. Ask the user if not known.
|
|
45
|
+
|
|
46
|
+
### 2. Create a Browser Session
|
|
47
|
+
Call \`browser_create_session\` to get a sessionId.
|
|
48
|
+
|
|
49
|
+
### 3. Iterative Build Loop — For EACH step:
|
|
50
|
+
|
|
51
|
+
**a. ACT — Perform the browser action**
|
|
52
|
+
- Call \`browser_act\` with a natural-language description of what to do
|
|
53
|
+
- Be specific: "navigate to ${targetUrl}", "click the Submit button", "type 'john@example.com' into the email input field"
|
|
54
|
+
|
|
55
|
+
**b. VERIFY — Confirm the action worked**
|
|
56
|
+
- Call \`browser_screenshot\` to see the current state
|
|
57
|
+
- If the action didn't produce the expected result, retry with a more specific instruction
|
|
58
|
+
|
|
59
|
+
**c. EXTRACT — Get data if needed**
|
|
60
|
+
- Call \`browser_extract\` with instructions like "extract the patient name and date of birth"
|
|
61
|
+
- This returns structured data from the page
|
|
62
|
+
|
|
63
|
+
**d. SAVE — Persist as a workflow step**
|
|
64
|
+
- Call \`create_browser_rpa_flow\` with the action type and payload
|
|
65
|
+
- For the first step, use actionType "create_session"
|
|
66
|
+
- For navigation/interaction steps, use actionType "act"
|
|
67
|
+
- For data extraction steps, use actionType "extract"
|
|
68
|
+
- For cleanup, use actionType "close_session"
|
|
69
|
+
|
|
70
|
+
### 4. End-to-End Validation
|
|
71
|
+
- Run the full workflow via \`execute_workflow\`
|
|
72
|
+
- Verify the final state
|
|
73
|
+
|
|
74
|
+
### 5. Iterate with the User
|
|
75
|
+
- Present the completed workflow
|
|
76
|
+
- Make adjustments as needed
|
|
77
|
+
|
|
78
|
+
## Important Rules
|
|
79
|
+
- **Always verify actions with screenshots** before saving
|
|
80
|
+
- **Use \`create_browser_rpa_flow\`** to save steps — it generates the correct \`lam.httpRequest\` wrapper
|
|
81
|
+
- **Use \`{{config.variables}}\`** for credentials (bearerToken, baseUrl, etc.)
|
|
82
|
+
- **Be specific in actions** — natural language should be unambiguous
|
|
83
|
+
- **Handle 2FA/MFA** — if login requires verification codes, use waitForInput patterns
|
|
84
|
+
- **One action per step** — keep steps focused and debuggable`,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=build-browser-rpa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-browser-rpa.js","sourceRoot":"","sources":["../../src/prompts/build-browser-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,4BAA4B,EAC5B,4NAA4N,EAC5N;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CACP,mHAAmH,CACpH;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,CAAC,sCAAsC,CAAC;QACnD,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,sEAAsE,CAAC;KACpF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACvD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;EAGhB,IAAI;;;EAGJ,SAAS;;;MAGL,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,2BAA2B,UAAU,+BAA+B,CAAC,CAAC,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;8BAuBxH,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8DA+BuB;iBACnD;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +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,QAgL5C"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register({ server }) {
|
|
3
|
+
server.prompt("build-rpa-workflow", "Iteratively build an RPA workflow on a VM using the Laminar Desktop Service. Guides you through connecting to the VM, researching the target app's UI framework, taking screenshots, inspecting UI elements, writing and testing RPA scripts, and saving each working step as a Laminar workflow flow.", {
|
|
4
|
+
workspaceId: z.string().describe("Laminar workspace ID"),
|
|
5
|
+
task: z
|
|
6
|
+
.string()
|
|
7
|
+
.describe("Description of what to automate (e.g. 'Log into Centricity, navigate to Documents, download the latest report')"),
|
|
8
|
+
appName: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Name of the application to automate (e.g. 'Centricity', 'SAP GUI', 'Epic Hyperspace')"),
|
|
11
|
+
workflowId: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
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 Laminar platform. Your goal is to iteratively create automation steps that run on a VM via the Laminar Desktop Service (LDS).
|
|
22
|
+
|
|
23
|
+
## Task
|
|
24
|
+
${task}
|
|
25
|
+
|
|
26
|
+
## Target Application
|
|
27
|
+
${appName}
|
|
28
|
+
|
|
29
|
+
## Workspace
|
|
30
|
+
ID: ${workspaceId}${workflowId ? `\nExisting workflow ID: ${workflowId} (add steps to this workflow)` : "\nCreate a new workflow for this automation."}
|
|
31
|
+
|
|
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 Laminar 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
|
+
## Procedure
|
|
49
|
+
|
|
50
|
+
### 1. Connect to the VM
|
|
51
|
+
If no VM is connected, ask for the **Cloudflare Tunnel URL** and call \`vm_connect\`.
|
|
52
|
+
|
|
53
|
+
### 2. Research the Target Application
|
|
54
|
+
Based on "${appName}", pick the UI automation framework:
|
|
55
|
+
- **.NET / WPF / WinForms** → \`uiautomation\` (default) or \`pywinauto\`
|
|
56
|
+
- **Java / Swing** → \`jab\` (Java Access Bridge)
|
|
57
|
+
- **Electron / web-based desktop** → \`pywinauto\` or pyautogui
|
|
58
|
+
- **Legacy Win32** → \`uiautomation\`
|
|
59
|
+
|
|
60
|
+
Start with \`uiautomation\` if unsure.
|
|
61
|
+
|
|
62
|
+
### 3. Initial Survey (ALWAYS do this first)
|
|
63
|
+
Before writing any automation:
|
|
64
|
+
1. \`vm_screenshot\` — see the desktop state
|
|
65
|
+
2. \`vm_inspect_ui\` mode \`screen_info\` — get resolution
|
|
66
|
+
3. \`vm_inspect_ui\` mode \`window_list\` — list windows
|
|
67
|
+
4. Verify the target app is running
|
|
68
|
+
|
|
69
|
+
### 4. Iterative Build Loop — For EACH step:
|
|
70
|
+
|
|
71
|
+
**a. OBSERVE — Understand the current state (REQUIRED)**
|
|
72
|
+
- \`vm_screenshot\` to see the screen
|
|
73
|
+
- \`vm_inspect_ui\` with \`element_tree\` to map UI elements
|
|
74
|
+
- \`vm_inspect_ui\` with \`element_at_point\` for specific elements
|
|
75
|
+
|
|
76
|
+
**b. WRITE — Create the Python RPA script**
|
|
77
|
+
- Use the appropriate framework (pyautogui for mouse/keyboard, uiautomation/pywinauto for element-based)
|
|
78
|
+
- Include error handling and waits
|
|
79
|
+
- Explain what it does before executing
|
|
80
|
+
|
|
81
|
+
**c. VALIDATE — Test on the VM (REQUIRED)**
|
|
82
|
+
- \`vm_execute_script\` — run the script
|
|
83
|
+
- Or use \`debug_rpa_step\` for full before/after screenshots + diagnostics
|
|
84
|
+
- Fix and re-run if errors occur
|
|
85
|
+
|
|
86
|
+
**d. VERIFY — Confirm visually (REQUIRED)**
|
|
87
|
+
- \`vm_screenshot\` immediately after
|
|
88
|
+
- If result is wrong, go back to (b)
|
|
89
|
+
|
|
90
|
+
**e. SAVE — Call \`create_rpa_flow\` (only after c + d pass)**
|
|
91
|
+
- Pass the validated Python script, step name, description, flowId, and executionOrder
|
|
92
|
+
- The tool handles all JS wrapping automatically
|
|
93
|
+
- Default dispatch: \`cloudflare_tunnel\` (uses \`lam.httpRequest\`)
|
|
94
|
+
|
|
95
|
+
### 5. End-to-End Validation
|
|
96
|
+
After all steps are built:
|
|
97
|
+
- \`execute_workflow\` to run the full sequence
|
|
98
|
+
- \`vm_screenshot\` to verify final state
|
|
99
|
+
- \`diagnose_execution\` if anything fails
|
|
100
|
+
|
|
101
|
+
### 6. Iterate with the User
|
|
102
|
+
- Present completed workflow summary
|
|
103
|
+
- Make adjustments, re-validate changed steps
|
|
104
|
+
|
|
105
|
+
## Data Extraction Strategy
|
|
106
|
+
|
|
107
|
+
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.**
|
|
108
|
+
|
|
109
|
+
### Priority 1: Accessibility Tree (most reliable)
|
|
110
|
+
- \`vm_inspect_ui\` with \`element_tree\` on the target window
|
|
111
|
+
- If the tree exposes text values, this is the most reliable method
|
|
112
|
+
- Use \`element_at_point\` for specific fields
|
|
113
|
+
- Use \`focused_element\` to read the current field
|
|
114
|
+
|
|
115
|
+
### Priority 2: Open Accessible Dialogs
|
|
116
|
+
- Many apps expose more data when you open edit/detail dialogs
|
|
117
|
+
- Double-click on a row or click "Edit" to open a modal — the modal often has better accessibility support
|
|
118
|
+
- Then use \`element_tree\` on the modal
|
|
119
|
+
|
|
120
|
+
### Priority 3: Clipboard Extraction
|
|
121
|
+
- Use \`vm_execute_script\` to click a field, then Ctrl+A, Ctrl+C
|
|
122
|
+
- Call \`vm_read_clipboard\` to get the copied text
|
|
123
|
+
- Works for individual fields, text areas, and some grid cells
|
|
124
|
+
|
|
125
|
+
### Priority 4: Keyboard Navigation
|
|
126
|
+
- Tab through fields, reading each via \`vm_inspect_ui\` \`focused_element\`
|
|
127
|
+
- Useful when the accessibility tree returns element structure but not values
|
|
128
|
+
|
|
129
|
+
### Priority 5: Zoomed Screenshot
|
|
130
|
+
- Use \`vm_screenshot_region\` to crop a specific area for better resolution
|
|
131
|
+
- Only for small text that can't be accessed any other way
|
|
132
|
+
|
|
133
|
+
### Priority 6: Alternative Application Paths
|
|
134
|
+
- Think creatively! Look for:
|
|
135
|
+
- Reports or Print menus that export data
|
|
136
|
+
- List/Search views with better accessibility
|
|
137
|
+
- CLI tools or command-line interfaces the app provides
|
|
138
|
+
- Export to CSV/clipboard options
|
|
139
|
+
- Alternative windows/dialogs that show the same data more accessibly
|
|
140
|
+
- Use \`vm_execute_script\` to run Python code that queries the app's data directly if a CLI or API exists
|
|
141
|
+
|
|
142
|
+
### Priority 7: Full Screenshot (VERIFICATION ONLY)
|
|
143
|
+
- Full desktop screenshots are for **verifying actions worked**, NOT for reading data
|
|
144
|
+
- If you must use a screenshot to read data, acknowledge it's unreliable and suggest a better approach to the user
|
|
145
|
+
|
|
146
|
+
## Debugging Tools
|
|
147
|
+
|
|
148
|
+
- **\`debug_rpa_step\`** — runs a script with before/after screenshots and full diagnostics (stdout, stderr, exit code). Use during development.
|
|
149
|
+
- **\`vm_reset_state\`** — Smart Launch: close dialogs, reset app to known state. Use before testing.
|
|
150
|
+
- **\`vm_read_clipboard\`** — read clipboard after a copy operation.
|
|
151
|
+
- **\`vm_screenshot_region\`** — crop/zoom a region for better text reading.
|
|
152
|
+
- **\`batch_test_rpa\`** — run the workflow with multiple test inputs.
|
|
153
|
+
|
|
154
|
+
## Important Rules
|
|
155
|
+
- **VALIDATE BEFORE SAVING** — no exceptions unless user explicitly opts out
|
|
156
|
+
- **Use \`create_rpa_flow\`** — never construct JS wrappers manually
|
|
157
|
+
- **Use \`{{config.variables}}\` for secrets** — never hardcode credentials
|
|
158
|
+
- **Combine extraction methods** — accessibility tree + clipboard + screenshots
|
|
159
|
+
- **Start simple** — get basic automation working before adding sophistication
|
|
160
|
+
- **Add waits** — use \`time.sleep()\` or element-wait patterns between actions
|
|
161
|
+
- **Handle errors** — try/except with meaningful messages
|
|
162
|
+
- **Keep scripts focused** — one logical action per step`,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=build-rpa.js.map
|
|
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;;;;;YAwB1I,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDA4GsC;iBAC9C;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-execution.d.ts","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,QAoDpD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { json } from "../helpers.js";
|
|
3
|
+
export function register({ server, client }) {
|
|
4
|
+
server.prompt("debug-workflow-execution", "Analyze a failed workflow execution and suggest fixes", {
|
|
5
|
+
workflowId: z.string().describe("Workflow ID to debug"),
|
|
6
|
+
executionId: z.string().describe("Failed execution ID"),
|
|
7
|
+
}, async ({ workflowId, executionId }) => {
|
|
8
|
+
const wId = parseInt(workflowId);
|
|
9
|
+
const eId = parseInt(executionId);
|
|
10
|
+
let executionData;
|
|
11
|
+
let flowsData;
|
|
12
|
+
try {
|
|
13
|
+
executionData = await client().getExecution(wId, eId);
|
|
14
|
+
flowsData = await client().getWorkflowFlows(wId);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
return {
|
|
18
|
+
messages: [
|
|
19
|
+
{
|
|
20
|
+
role: "user",
|
|
21
|
+
content: {
|
|
22
|
+
type: "text",
|
|
23
|
+
text: `Failed to fetch execution data: ${e.message}`,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
messages: [
|
|
31
|
+
{
|
|
32
|
+
role: "user",
|
|
33
|
+
content: {
|
|
34
|
+
type: "text",
|
|
35
|
+
text: `Please debug this Laminar workflow execution.
|
|
36
|
+
|
|
37
|
+
## Workflow Flows (Steps):
|
|
38
|
+
${json(flowsData)}
|
|
39
|
+
|
|
40
|
+
## Execution Details:
|
|
41
|
+
${json(executionData)}
|
|
42
|
+
|
|
43
|
+
Analyze the execution, identify failures, explain root causes, and suggest specific code fixes for the failing steps. Use the Laminar workflow specification (available via the laminar-workflow-guide prompt) for correct syntax.`,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=debug-execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-execution.js","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAY;IACnD,MAAM,CAAC,MAAM,CACX,0BAA0B,EAC1B,uDAAuD,EACvD;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACvD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;KACxD,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE;QACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClC,IAAI,aAAkB,CAAC;QACvB,IAAI,SAAc,CAAC;QAEnB,IAAI,CAAC;YACH,aAAa,GAAG,MAAM,MAAM,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACtD,SAAS,GAAG,MAAM,MAAM,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,mCAAmC,CAAC,CAAC,OAAO,EAAE;yBACrD;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;;;EAGlB,IAAI,CAAC,SAAS,CAAC;;;EAGf,IAAI,CAAC,aAAa,CAAC;;mOAE8M;qBACtN;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-guide.d.ts","sourceRoot":"","sources":["../../src/prompts/workflow-guide.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QAkL5C"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
export function register({ server }) {
|
|
2
|
+
server.prompt("laminar-workflow-guide", "Comprehensive guide for creating and editing Laminar workflows — step types, data access patterns, available libraries, and best practices", {}, async () => ({
|
|
3
|
+
messages: [
|
|
4
|
+
{
|
|
5
|
+
role: "user",
|
|
6
|
+
content: {
|
|
7
|
+
type: "text",
|
|
8
|
+
text: `Please use this Laminar platform specification when creating or editing workflows:
|
|
9
|
+
|
|
10
|
+
# Laminar Workflow Specification
|
|
11
|
+
|
|
12
|
+
## Step Structure
|
|
13
|
+
Every step is a JSON object with these fields:
|
|
14
|
+
- \`name\`: (string) Descriptive name
|
|
15
|
+
- \`description\`: (string) Detailed explanation
|
|
16
|
+
- \`program\`: (string) Code to execute (JS or Python)
|
|
17
|
+
- \`executionOrder\`: (integer) Position in workflow (starts at 1)
|
|
18
|
+
- \`flowType\`: (string) "HTTP_REQUEST", "GENERAL_FUNCTION", "SHELL_SCRIPT", "RPA"
|
|
19
|
+
- \`language\`: (string) "js" or "py" (NOTE: RPA flows must ALWAYS use "js")
|
|
20
|
+
|
|
21
|
+
## Program Signatures
|
|
22
|
+
**Python (py):**
|
|
23
|
+
\`\`\`python
|
|
24
|
+
def transform(data):
|
|
25
|
+
# Your logic here
|
|
26
|
+
return {}
|
|
27
|
+
\`\`\`
|
|
28
|
+
|
|
29
|
+
**JavaScript (js):**
|
|
30
|
+
\`\`\`javascript
|
|
31
|
+
(data) => {
|
|
32
|
+
// Your code here
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
\`\`\`
|
|
36
|
+
|
|
37
|
+
## Return Values by flowType
|
|
38
|
+
|
|
39
|
+
### HTTP_REQUEST
|
|
40
|
+
\`\`\`json
|
|
41
|
+
{
|
|
42
|
+
"lam.httpRequest": {
|
|
43
|
+
"method": "GET|POST|PUT|DELETE|PATCH",
|
|
44
|
+
"url": "String",
|
|
45
|
+
"headers": "Object (optional)",
|
|
46
|
+
"pathParams": "Object (optional)",
|
|
47
|
+
"queryParams": "Object (optional)",
|
|
48
|
+
"body": "Object (optional)",
|
|
49
|
+
"authentication": {
|
|
50
|
+
"type": "basic|bearer|oauth2|apikey",
|
|
51
|
+
"token": "{{config.token}}"
|
|
52
|
+
},
|
|
53
|
+
"retry": { "maxAttempts": "Number" },
|
|
54
|
+
"pagination": {
|
|
55
|
+
"next": { "queryParams": {}, "headers": {}, "body": {} },
|
|
56
|
+
"stopCondition": "JS function receiving ctx",
|
|
57
|
+
"maxPages": 10
|
|
58
|
+
},
|
|
59
|
+
"loopUntil": {
|
|
60
|
+
"condition": "(ctx) => ctx.response.status === 'completed'",
|
|
61
|
+
"maxAttempts": 20,
|
|
62
|
+
"strategy": "exponential",
|
|
63
|
+
"initialDelay": "2s",
|
|
64
|
+
"maxDelay": "60s",
|
|
65
|
+
"multiplier": 2
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
Multiple requests: use \`"lam.httpRequests"\` (plural) with an array.
|
|
72
|
+
|
|
73
|
+
### SHELL_SCRIPT
|
|
74
|
+
\`\`\`json
|
|
75
|
+
{
|
|
76
|
+
"lam.shell": {
|
|
77
|
+
"script": "Bash script as string",
|
|
78
|
+
"environment": {},
|
|
79
|
+
"timeout": 300,
|
|
80
|
+
"binaryDataIds": []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
\`\`\`
|
|
84
|
+
|
|
85
|
+
### RPA (Desktop Automation)
|
|
86
|
+
**IMPORTANT: Use the \`create_rpa_flow\` tool to save RPA steps.** It accepts your validated Python script and automatically wraps it in the correct JS format. You do NOT need to construct the wrapper yourself.
|
|
87
|
+
|
|
88
|
+
RPA flows internally use \`language: "js"\` with the Python embedded in a JS arrow function. Two dispatch patterns exist:
|
|
89
|
+
- **\`lam.httpRequest\`** (Cloudflare Tunnel — default) — sends the script to the VM via HTTP
|
|
90
|
+
- **\`lam.rpa\`** (channelId) — sends via pub/sub channel
|
|
91
|
+
|
|
92
|
+
The \`create_rpa_flow\` tool handles both patterns via the \`dispatchPattern\` parameter (default: \`cloudflare_tunnel\`).
|
|
93
|
+
|
|
94
|
+
**NEVER** save raw Python as the program for an RPA flow. **NEVER** manually construct the JS wrapper — use \`create_rpa_flow\`.
|
|
95
|
+
|
|
96
|
+
### Configuration Updates
|
|
97
|
+
\`\`\`json
|
|
98
|
+
{
|
|
99
|
+
"lam.updateConfig": {
|
|
100
|
+
"configurationId": "my-config",
|
|
101
|
+
"properties": [{ "key": "k", "value": "v" }],
|
|
102
|
+
"createIfNotExists": true,
|
|
103
|
+
"configurationName": "Auto-generated Config"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
108
|
+
### Redis Key-Value Store
|
|
109
|
+
\`\`\`json
|
|
110
|
+
{
|
|
111
|
+
"lam.kvStore": {
|
|
112
|
+
"operation": "set|get|delete|exists|list|increment|decrement|transaction",
|
|
113
|
+
"key": "user:session:token",
|
|
114
|
+
"value": {},
|
|
115
|
+
"ttl": 3600,
|
|
116
|
+
"redisUrl": "{{config.redisUrl}}"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
### Cron Job Management
|
|
122
|
+
\`\`\`json
|
|
123
|
+
{
|
|
124
|
+
"lam.cron": {
|
|
125
|
+
"operation": "create|update|delete",
|
|
126
|
+
"name": "Daily Report",
|
|
127
|
+
"schedule": "0 0 9 * * *",
|
|
128
|
+
"url": "https://api.laminar.run/workflow/execute/external/{id}?api_key=key",
|
|
129
|
+
"body": {}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
\`\`\`
|
|
133
|
+
|
|
134
|
+
### Custom Response (lam.response)
|
|
135
|
+
\`\`\`json
|
|
136
|
+
{
|
|
137
|
+
"lam.response": {
|
|
138
|
+
"statusCode": 200,
|
|
139
|
+
"message": "Success",
|
|
140
|
+
"data": {},
|
|
141
|
+
"error": { "code": "ERROR_CODE", "message": "Error description" }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
\`\`\`
|
|
145
|
+
Note: Workflow exits immediately when lam.response is encountered.
|
|
146
|
+
|
|
147
|
+
## Data Access Patterns
|
|
148
|
+
- \`data.input\`: Original workflow input
|
|
149
|
+
- \`data.step_N.response\`: HTTP request output from step N
|
|
150
|
+
- \`data.step_N.data\`: General function output from step N
|
|
151
|
+
- \`data.step_N.stdout\`: Shell output from step N
|
|
152
|
+
- \`data.step_N.stderr\`: Shell error from step N
|
|
153
|
+
- \`data.step_N.cronJobId\`: Cron job ID from step N
|
|
154
|
+
- \`data.step_N.response["lam.kvStore.value"]\`: KV store value
|
|
155
|
+
- \`data.step_N.response["lam.binaryDataId"]\`: File download reference
|
|
156
|
+
|
|
157
|
+
## Available Libraries
|
|
158
|
+
- **Python:** json, datetime, math, statistics, collections, itertools, functools, re, copy, decimal, csv, io, dataclasses, typing, enum
|
|
159
|
+
- **JavaScript:** lodash (as _), date-fns (format, parseISO)
|
|
160
|
+
|
|
161
|
+
## Security
|
|
162
|
+
Use \`{{config.variableName}}\` for sensitive values (API keys, tokens, passwords). These reference configuration store properties.
|
|
163
|
+
|
|
164
|
+
## Best Practices
|
|
165
|
+
1. **Minimize steps** — combine operations when logical, fewer steps = faster execution
|
|
166
|
+
2. **Don't JSON.stringify request bodies** — pass objects directly
|
|
167
|
+
3. **File downloads** auto-create \`lam.binaryDataId\` — don't process as text
|
|
168
|
+
4. **Use {{config.variables}}** for sensitive data, not hardcoded values
|
|
169
|
+
5. **Access errors** via \`data.step_N.response.error\` and \`data.step_N.response.statusCode\``,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=workflow-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-guide.js","sourceRoot":"","sources":["../../src/prompts/workflow-guide.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,wBAAwB,EACxB,4IAA4I,EAC5I,EAAE,EACF,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gGAiK8E;iBACrF;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional service clients: Elasticsearch + CRON.
|
|
3
|
+
* Only instantiated when configured — otherwise tools degrade gracefully.
|
|
4
|
+
*/
|
|
5
|
+
import type { ElasticsearchConfig, CronConfig } from "./config.js";
|
|
6
|
+
export interface ESSearchParams {
|
|
7
|
+
workspaceId: string;
|
|
8
|
+
workflowId?: string;
|
|
9
|
+
workflowIds?: string[];
|
|
10
|
+
query?: string;
|
|
11
|
+
startDate?: string;
|
|
12
|
+
endDate?: string;
|
|
13
|
+
status?: string;
|
|
14
|
+
includeGlobalObject?: boolean;
|
|
15
|
+
rawQuery?: string;
|
|
16
|
+
fuzzy?: boolean;
|
|
17
|
+
size?: number;
|
|
18
|
+
from?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class ElasticsearchService {
|
|
21
|
+
private endpoint;
|
|
22
|
+
private apiKey;
|
|
23
|
+
private indexName;
|
|
24
|
+
constructor(config: ElasticsearchConfig);
|
|
25
|
+
private esRequest;
|
|
26
|
+
search(params: ESSearchParams): Promise<{
|
|
27
|
+
warning?: string | undefined;
|
|
28
|
+
hits: any;
|
|
29
|
+
total: any;
|
|
30
|
+
took: any;
|
|
31
|
+
}>;
|
|
32
|
+
private formatResults;
|
|
33
|
+
}
|
|
34
|
+
export declare class CronService {
|
|
35
|
+
private apiBase;
|
|
36
|
+
private apiKey;
|
|
37
|
+
constructor(config: CronConfig);
|
|
38
|
+
private request;
|
|
39
|
+
listJobs(workflowId?: string): Promise<any[]>;
|
|
40
|
+
getJob(jobId: string): Promise<any>;
|
|
41
|
+
createJob(job: {
|
|
42
|
+
name: string;
|
|
43
|
+
schedule: string;
|
|
44
|
+
url: string;
|
|
45
|
+
body?: Record<string, any>;
|
|
46
|
+
enabled?: boolean;
|
|
47
|
+
max_runs?: number | null;
|
|
48
|
+
is_temporary?: boolean;
|
|
49
|
+
}): Promise<any>;
|
|
50
|
+
updateJob(jobId: string, updates: {
|
|
51
|
+
name?: string;
|
|
52
|
+
schedule?: string;
|
|
53
|
+
url?: string;
|
|
54
|
+
body?: Record<string, any>;
|
|
55
|
+
enabled?: boolean;
|
|
56
|
+
}): Promise<any>;
|
|
57
|
+
toggleJob(jobId: string): Promise<any>;
|
|
58
|
+
deleteJob(jobId: string): Promise<void>;
|
|
59
|
+
triggerJob(jobId: string): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOnE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,mBAAmB;YAMzB,SAAS;IAmBjB,MAAM,CAAC,MAAM,EAAE,cAAc;;;;;;IAmJnC,OAAO,CAAC,aAAa;CAyBtB;AAID,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,UAAU;YAKhB,OAAO;IA+Bf,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM;IAY5B,MAAM,CAAC,KAAK,EAAE,MAAM;IAKpB,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;IASK,SAAS,CACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB;IAUG,SAAS,CAAC,KAAK,EAAE,MAAM;IAKvB,SAAS,CAAC,KAAK,EAAE,MAAM;IAIvB,UAAU,CAAC,KAAK,EAAE,MAAM;CAG/B"}
|