@minicor/mcp-server 2.0.7 → 3.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 +29 -2
- package/dist/__tests__/helpers.test.js +50 -0
- package/dist/__tests__/helpers.test.js.map +1 -1
- package/dist/__tests__/state.test.d.ts +2 -0
- package/dist/__tests__/state.test.d.ts.map +1 -0
- package/dist/__tests__/state.test.js +90 -0
- package/dist/__tests__/state.test.js.map +1 -0
- package/dist/__tests__/vm-service-client.test.d.ts +2 -0
- package/dist/__tests__/vm-service-client.test.d.ts.map +1 -0
- package/dist/__tests__/vm-service-client.test.js +80 -0
- package/dist/__tests__/vm-service-client.test.js.map +1 -0
- package/dist/agent-service-client.d.ts +34 -0
- package/dist/agent-service-client.d.ts.map +1 -0
- package/dist/agent-service-client.js +64 -0
- package/dist/agent-service-client.js.map +1 -0
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +27 -7
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/lds-client.d.ts +15 -0
- package/dist/lds-client.d.ts.map +1 -1
- package/dist/lds-client.js +11 -6
- package/dist/lds-client.js.map +1 -1
- package/dist/lib.d.ts +36 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +79 -0
- package/dist/lib.js.map +1 -0
- package/dist/prompts/build-rpa.d.ts.map +1 -1
- package/dist/prompts/build-rpa.js +39 -5
- package/dist/prompts/build-rpa.js.map +1 -1
- package/dist/state.d.ts +10 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +9 -0
- package/dist/state.js.map +1 -1
- package/dist/tools/{stats.d.ts → agents.d.ts} +1 -1
- package/dist/tools/agents.d.ts.map +1 -0
- package/dist/tools/agents.js +78 -0
- package/dist/tools/agents.js.map +1 -0
- package/dist/tools/issues.d.ts.map +1 -1
- package/dist/tools/issues.js +12 -9
- package/dist/tools/issues.js.map +1 -1
- package/dist/tools/vm-rpa.d.ts.map +1 -1
- package/dist/tools/vm-rpa.js +71 -30
- package/dist/tools/vm-rpa.js.map +1 -1
- package/dist/tools/vm.d.ts.map +1 -1
- package/dist/tools/vm.js +81 -12
- package/dist/tools/vm.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vm-service-client.d.ts +24 -0
- package/dist/vm-service-client.d.ts.map +1 -0
- package/dist/vm-service-client.js +23 -0
- package/dist/vm-service-client.js.map +1 -0
- package/package.json +7 -3
- package/dist/browser-client.d.ts +0 -42
- package/dist/browser-client.d.ts.map +0 -1
- package/dist/browser-client.js +0 -66
- package/dist/browser-client.js.map +0 -1
- package/dist/prompts/build-browser-rpa.d.ts +0 -3
- package/dist/prompts/build-browser-rpa.d.ts.map +0 -1
- package/dist/prompts/build-browser-rpa.js +0 -90
- package/dist/prompts/build-browser-rpa.js.map +0 -1
- package/dist/prompts/build-nerve-rpa.d.ts +0 -3
- package/dist/prompts/build-nerve-rpa.d.ts.map +0 -1
- package/dist/prompts/build-nerve-rpa.js +0 -148
- package/dist/prompts/build-nerve-rpa.js.map +0 -1
- package/dist/services.d.ts +0 -61
- package/dist/services.d.ts.map +0 -1
- package/dist/services.js +0 -249
- package/dist/services.js.map +0 -1
- package/dist/tools/browser.d.ts +0 -3
- package/dist/tools/browser.d.ts.map +0 -1
- package/dist/tools/browser.js +0 -254
- package/dist/tools/browser.js.map +0 -1
- package/dist/tools/cron.d.ts +0 -3
- package/dist/tools/cron.d.ts.map +0 -1
- package/dist/tools/cron.js +0 -168
- package/dist/tools/cron.js.map +0 -1
- package/dist/tools/elasticsearch.d.ts +0 -3
- package/dist/tools/elasticsearch.d.ts.map +0 -1
- package/dist/tools/elasticsearch.js +0 -248
- package/dist/tools/elasticsearch.js.map +0 -1
- package/dist/tools/stats.d.ts.map +0 -1
- package/dist/tools/stats.js +0 -18
- package/dist/tools/stats.js.map +0 -1
package/README.md
CHANGED
|
@@ -71,7 +71,8 @@ Use the `get_lds_setup_guide` tool for detailed step-by-step instructions.
|
|
|
71
71
|
|
|
72
72
|
| Tool | What it does |
|
|
73
73
|
| ---------------------- | ------------------------------------------------------------------------------------------ |
|
|
74
|
-
| `
|
|
74
|
+
| `vm_list` | Discover available VMs (returns ID, name, status, tunnel URL) |
|
|
75
|
+
| `vm_connect` | Connect to VM via LDS Cloudflare tunnel URL or VM ID |
|
|
75
76
|
| `vm_disconnect` | Disconnect from VM |
|
|
76
77
|
| `vm_status` | Health check for the connected VM |
|
|
77
78
|
| `vm_screenshot` | Full-screen capture of the VM desktop |
|
|
@@ -138,6 +139,32 @@ Workflows that encounter 2FA prompts use these tools to auto-resolve OTP challen
|
|
|
138
139
|
|
|
139
140
|
Scripts reference credentials as `{{config.propertyKey}}` — resolved at runtime by the workflow engine.
|
|
140
141
|
|
|
142
|
+
### Issues
|
|
143
|
+
|
|
144
|
+
| Tool | What it does |
|
|
145
|
+
| -------------- | ---------------------------------------------- |
|
|
146
|
+
| `list_issues` | List all issues in a workspace |
|
|
147
|
+
| `get_issue` | Get a specific issue with full description |
|
|
148
|
+
| `create_issue` | Create an issue (supports Markdown) |
|
|
149
|
+
| `update_issue` | Update title, description, status, or assignee |
|
|
150
|
+
| `delete_issue` | Delete an issue |
|
|
151
|
+
|
|
152
|
+
Agents use Issues to persist context across runs with the `[Agent:<name>]` title convention:
|
|
153
|
+
|
|
154
|
+
- `[Agent:my-bot] Rules` — learned behaviors (e.g., "login page takes 15s to load")
|
|
155
|
+
- `[Agent:my-bot] Context` — persistent state (URLs, credential rotation dates)
|
|
156
|
+
- `[Agent:my-bot] Session 2026-04-09` — run summaries
|
|
157
|
+
|
|
158
|
+
### Agents
|
|
159
|
+
|
|
160
|
+
| Tool | What it does |
|
|
161
|
+
| -------------- | --------------------------------------------------------------- |
|
|
162
|
+
| `list_agents` | List agents in a workspace |
|
|
163
|
+
| `get_agent` | Get agent details (task, mode, VM, run stats) |
|
|
164
|
+
| `create_agent` | Create an agent (on-demand, scheduled, or workflow monitor mode) |
|
|
165
|
+
|
|
166
|
+
Agents are autonomous runners that execute tasks on VMs using MCP tools. After building a workflow, the `build-rpa-workflow` prompt offers to create a monitoring agent that watches for failures and auto-recovers.
|
|
167
|
+
|
|
141
168
|
### Workflow Sync
|
|
142
169
|
|
|
143
170
|
| Tool | What it does |
|
|
@@ -151,7 +178,7 @@ Scripts reference credentials as `{{config.propertyKey}}` — resolved at runtim
|
|
|
151
178
|
|
|
152
179
|
| Prompt | What it does |
|
|
153
180
|
| -------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
154
|
-
| `build-rpa-workflow` | Guided automation building: strategy selection, iterative build loop, Minicor testing,
|
|
181
|
+
| `build-rpa-workflow` | Guided automation building: strategy selection, iterative build loop, per-step Minicor testing, idempotency, context persistence, and agent setup |
|
|
155
182
|
| `debug-workflow-execution` | Analyze a failed execution with VM-aware debugging and replay |
|
|
156
183
|
| `minicor-workflow-guide` | Full workflow specification: step types, data access, keywords, libraries |
|
|
157
184
|
| `2fa-workflow-guide` | Handling 2FA in workflows: provisioning channels, TOTP secrets, auto-resolving OTP codes |
|
|
@@ -66,5 +66,55 @@ describe("buildRpaProgram", () => {
|
|
|
66
66
|
expect(program).toContain('Step \\"with\\" quotes');
|
|
67
67
|
expect(program).toContain('Desc \\"here\\"');
|
|
68
68
|
});
|
|
69
|
+
it("omits state descriptions when not provided", () => {
|
|
70
|
+
const program = buildRpaProgram('print("hello")', "cloudflare_tunnel", "step-1", "Step 1", "First step");
|
|
71
|
+
expect(program).not.toContain("expectedPreState");
|
|
72
|
+
expect(program).not.toContain("expectedPostState");
|
|
73
|
+
});
|
|
74
|
+
it("embeds expectedPreState in cloudflare_tunnel body", () => {
|
|
75
|
+
const program = buildRpaProgram('print("hello")', "cloudflare_tunnel", "step-1", "Step 1", "First step", "Login page is visible");
|
|
76
|
+
expect(program).toContain('"expectedPreState": "Login page is visible"');
|
|
77
|
+
expect(program).not.toContain("expectedPostState");
|
|
78
|
+
});
|
|
79
|
+
it("embeds expectedPostState in cloudflare_tunnel body", () => {
|
|
80
|
+
const program = buildRpaProgram('print("hello")', "cloudflare_tunnel", "step-1", "Step 1", "First step", undefined, "Dashboard is showing");
|
|
81
|
+
expect(program).not.toContain("expectedPreState");
|
|
82
|
+
expect(program).toContain('"expectedPostState": "Dashboard is showing"');
|
|
83
|
+
});
|
|
84
|
+
it("embeds both state descriptions in cloudflare_tunnel body", () => {
|
|
85
|
+
const program = buildRpaProgram('print("hello")', "cloudflare_tunnel", "step-1", "Step 1", "First step", "Login page is visible", "Dashboard is showing");
|
|
86
|
+
expect(program).toContain('"expectedPreState": "Login page is visible"');
|
|
87
|
+
expect(program).toContain('"expectedPostState": "Dashboard is showing"');
|
|
88
|
+
expect(program).toContain("lam.httpRequest");
|
|
89
|
+
});
|
|
90
|
+
it("embeds state descriptions in channel (lam.rpa) pattern", () => {
|
|
91
|
+
const program = buildRpaProgram('print("hello")', "channel", "step-1", "Step 1", "First step", "Login page visible", "Dashboard visible");
|
|
92
|
+
expect(program).toContain("lam.rpa");
|
|
93
|
+
expect(program).toContain('"expectedPreState": "Login page visible"');
|
|
94
|
+
expect(program).toContain('"expectedPostState": "Dashboard visible"');
|
|
95
|
+
expect(program).not.toContain("lam.httpRequest");
|
|
96
|
+
});
|
|
97
|
+
it("embeds state descriptions in browser pattern", () => {
|
|
98
|
+
const program = buildRpaProgram('print("hello")', "browser", "step-1", "Step 1", "First step", "Browser tab open", "Form submitted");
|
|
99
|
+
expect(program).toContain("/execute/browser");
|
|
100
|
+
expect(program).toContain('"expectedPreState": "Browser tab open"');
|
|
101
|
+
expect(program).toContain('"expectedPostState": "Form submitted"');
|
|
102
|
+
});
|
|
103
|
+
it("escapes double quotes in state descriptions", () => {
|
|
104
|
+
const program = buildRpaProgram("pass", "cloudflare_tunnel", "id", "name", "desc", 'Page shows "Login" button', 'Dialog says "Success"');
|
|
105
|
+
expect(program).toContain('Page shows \\"Login\\" button');
|
|
106
|
+
expect(program).toContain('Dialog says \\"Success\\"');
|
|
107
|
+
});
|
|
108
|
+
it("escapes newlines in state descriptions", () => {
|
|
109
|
+
const program = buildRpaProgram("pass", "cloudflare_tunnel", "id", "name", "desc", "Line one\nLine two");
|
|
110
|
+
expect(program).toContain("Line one\\nLine two");
|
|
111
|
+
expect(program).not.toContain("Line one\nLine two");
|
|
112
|
+
});
|
|
113
|
+
it("escapes backslashes in state descriptions", () => {
|
|
114
|
+
const program = buildRpaProgram("pass", "cloudflare_tunnel", "id", "name", "desc", "File at C:\\temp\\new folder", "Tab\there");
|
|
115
|
+
expect(program).toContain("C:\\\\temp\\\\new folder");
|
|
116
|
+
expect(program).toContain("Tab\\there");
|
|
117
|
+
expect(program).not.toContain("C:\\temp");
|
|
118
|
+
});
|
|
69
119
|
});
|
|
70
120
|
//# sourceMappingURL=helpers.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.test.js","sourceRoot":"","sources":["../../src/__tests__/helpers.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers.test.js","sourceRoot":"","sources":["../../src/__tests__/helpers.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { ldsConnection, setLdsConnection, ldsAuth, vmCache, setVmCache, getCachedVm, } from "../state.js";
|
|
3
|
+
describe("LdsConnection", () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
setLdsConnection(null);
|
|
6
|
+
});
|
|
7
|
+
it("starts as null", () => {
|
|
8
|
+
expect(ldsConnection).toBeNull();
|
|
9
|
+
});
|
|
10
|
+
it("stores connection with vmId and vmName", () => {
|
|
11
|
+
setLdsConnection({
|
|
12
|
+
url: "https://vm.example.com",
|
|
13
|
+
apiKey: "key",
|
|
14
|
+
serviceId: "svc",
|
|
15
|
+
vmId: 1,
|
|
16
|
+
vmName: "test-vm",
|
|
17
|
+
});
|
|
18
|
+
expect(ldsConnection).toEqual({
|
|
19
|
+
url: "https://vm.example.com",
|
|
20
|
+
apiKey: "key",
|
|
21
|
+
serviceId: "svc",
|
|
22
|
+
vmId: 1,
|
|
23
|
+
vmName: "test-vm",
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
it("returns auth when apiKey and serviceId are set", () => {
|
|
27
|
+
setLdsConnection({ url: "https://vm.example.com", apiKey: "k", serviceId: "s" });
|
|
28
|
+
expect(ldsAuth()).toEqual({ apiKey: "k", serviceId: "s" });
|
|
29
|
+
});
|
|
30
|
+
it("returns undefined auth when apiKey is missing", () => {
|
|
31
|
+
setLdsConnection({ url: "https://vm.example.com", serviceId: "s" });
|
|
32
|
+
expect(ldsAuth()).toBeUndefined();
|
|
33
|
+
});
|
|
34
|
+
it("returns undefined auth when serviceId is missing", () => {
|
|
35
|
+
setLdsConnection({ url: "https://vm.example.com", apiKey: "k" });
|
|
36
|
+
expect(ldsAuth()).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
it("clears connection on null", () => {
|
|
39
|
+
setLdsConnection({ url: "https://vm.example.com" });
|
|
40
|
+
setLdsConnection(null);
|
|
41
|
+
expect(ldsConnection).toBeNull();
|
|
42
|
+
expect(ldsAuth()).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("VM cache", () => {
|
|
46
|
+
const vm1 = {
|
|
47
|
+
id: 1,
|
|
48
|
+
vm_name: "alpha",
|
|
49
|
+
tunnel_url: "https://alpha.example.com",
|
|
50
|
+
api_key: "key-1",
|
|
51
|
+
service_id: "svc-1",
|
|
52
|
+
};
|
|
53
|
+
const vm2 = {
|
|
54
|
+
id: 2,
|
|
55
|
+
vm_name: "beta",
|
|
56
|
+
tunnel_url: null,
|
|
57
|
+
api_key: "key-2",
|
|
58
|
+
service_id: "svc-2",
|
|
59
|
+
};
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
setVmCache(null);
|
|
62
|
+
});
|
|
63
|
+
it("starts as null", () => {
|
|
64
|
+
expect(vmCache).toBeNull();
|
|
65
|
+
});
|
|
66
|
+
it("stores and retrieves VM cache", () => {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
setVmCache({ vms: [vm1, vm2], fetchedAt: now });
|
|
69
|
+
expect(vmCache).toEqual({ vms: [vm1, vm2], fetchedAt: now });
|
|
70
|
+
});
|
|
71
|
+
it("getCachedVm finds a VM by id", () => {
|
|
72
|
+
setVmCache({ vms: [vm1, vm2], fetchedAt: Date.now() });
|
|
73
|
+
expect(getCachedVm(1)).toEqual(vm1);
|
|
74
|
+
expect(getCachedVm(2)).toEqual(vm2);
|
|
75
|
+
});
|
|
76
|
+
it("getCachedVm returns undefined for unknown id", () => {
|
|
77
|
+
setVmCache({ vms: [vm1], fetchedAt: Date.now() });
|
|
78
|
+
expect(getCachedVm(999)).toBeUndefined();
|
|
79
|
+
});
|
|
80
|
+
it("getCachedVm returns undefined when cache is empty", () => {
|
|
81
|
+
expect(getCachedVm(1)).toBeUndefined();
|
|
82
|
+
});
|
|
83
|
+
it("clears cache on null", () => {
|
|
84
|
+
setVmCache({ vms: [vm1], fetchedAt: Date.now() });
|
|
85
|
+
setVmCache(null);
|
|
86
|
+
expect(vmCache).toBeNull();
|
|
87
|
+
expect(getCachedVm(1)).toBeUndefined();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=state.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-service-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vm-service-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { listVms } from "../vm-service-client.js";
|
|
3
|
+
describe("listVms", () => {
|
|
4
|
+
const originalFetch = globalThis.fetch;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
globalThis.fetch = vi.fn();
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
globalThis.fetch = originalFetch;
|
|
10
|
+
});
|
|
11
|
+
const baseUrl = "https://vm-service.example.com";
|
|
12
|
+
const apiKey = "ws-api-key-123";
|
|
13
|
+
const mockVms = [
|
|
14
|
+
{
|
|
15
|
+
id: 1,
|
|
16
|
+
vm_name: "test-vm",
|
|
17
|
+
deployment_status: "registered",
|
|
18
|
+
tunnel_url: "https://test-vm.example.com",
|
|
19
|
+
api_key: "vm-key-1",
|
|
20
|
+
service_id: "svc-1",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 2,
|
|
24
|
+
vm_name: "dev-vm",
|
|
25
|
+
deployment_status: "registered",
|
|
26
|
+
tunnel_url: null,
|
|
27
|
+
api_key: "vm-key-2",
|
|
28
|
+
service_id: "svc-2",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
const mockResponse = {
|
|
32
|
+
workspace_id: "1",
|
|
33
|
+
vms: mockVms,
|
|
34
|
+
total_vms: 2,
|
|
35
|
+
active_vms: 1,
|
|
36
|
+
};
|
|
37
|
+
const emptyResponse = { workspace_id: "1", vms: [], total_vms: 0, active_vms: 0 };
|
|
38
|
+
it("calls GET /vms/list with X-API-KEY header and extracts vms array", async () => {
|
|
39
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response(JSON.stringify(mockResponse), { status: 200 }));
|
|
40
|
+
const result = await listVms(baseUrl, apiKey);
|
|
41
|
+
expect(globalThis.fetch).toHaveBeenCalledWith(`${baseUrl}/vms/list`, { headers: { "X-API-KEY": apiKey } });
|
|
42
|
+
expect(result).toEqual(mockVms);
|
|
43
|
+
});
|
|
44
|
+
it("appends region query param when provided", async () => {
|
|
45
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response(JSON.stringify(emptyResponse), { status: 200 }));
|
|
46
|
+
await listVms(baseUrl, apiKey, { region: "us" });
|
|
47
|
+
const calledUrl = vi.mocked(globalThis.fetch).mock.calls[0][0];
|
|
48
|
+
expect(calledUrl).toBe(`${baseUrl}/vms/list?region=us`);
|
|
49
|
+
});
|
|
50
|
+
it("appends channel_id query param when provided", async () => {
|
|
51
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response(JSON.stringify(emptyResponse), { status: 200 }));
|
|
52
|
+
await listVms(baseUrl, apiKey, { channelId: "ch-42" });
|
|
53
|
+
const calledUrl = vi.mocked(globalThis.fetch).mock.calls[0][0];
|
|
54
|
+
expect(calledUrl).toBe(`${baseUrl}/vms/list?channel_id=ch-42`);
|
|
55
|
+
});
|
|
56
|
+
it("appends both query params when provided", async () => {
|
|
57
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response(JSON.stringify(emptyResponse), { status: 200 }));
|
|
58
|
+
await listVms(baseUrl, apiKey, { region: "ca", channelId: "ch-1" });
|
|
59
|
+
const calledUrl = vi.mocked(globalThis.fetch).mock.calls[0][0];
|
|
60
|
+
expect(calledUrl).toContain("region=ca");
|
|
61
|
+
expect(calledUrl).toContain("channel_id=ch-1");
|
|
62
|
+
});
|
|
63
|
+
it("omits query params when not provided", async () => {
|
|
64
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response(JSON.stringify(emptyResponse), { status: 200 }));
|
|
65
|
+
await listVms(baseUrl, apiKey, {});
|
|
66
|
+
const calledUrl = vi.mocked(globalThis.fetch).mock.calls[0][0];
|
|
67
|
+
expect(calledUrl).toBe(`${baseUrl}/vms/list`);
|
|
68
|
+
});
|
|
69
|
+
it("throws on non-ok response with status and body", async () => {
|
|
70
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(new Response("Unauthorized", { status: 401 }));
|
|
71
|
+
await expect(listVms(baseUrl, apiKey)).rejects.toThrow("VM service returned 401: Unauthorized");
|
|
72
|
+
});
|
|
73
|
+
it("throws on non-ok response even if body read fails", async () => {
|
|
74
|
+
const res = new Response(null, { status: 500 });
|
|
75
|
+
vi.spyOn(res, "text").mockRejectedValue(new Error("read error"));
|
|
76
|
+
vi.mocked(globalThis.fetch).mockResolvedValue(res);
|
|
77
|
+
await expect(listVms(baseUrl, apiKey)).rejects.toThrow("VM service returned 500:");
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=vm-service-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-service-client.test.js","sourceRoot":"","sources":["../../src/__tests__/vm-service-client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent management client that routes through the Minicor platform proxy.
|
|
3
|
+
*
|
|
4
|
+
* /api/agents/[...path] proxies to the agent service and handles auth —
|
|
5
|
+
* the MCP sends its existing bearer token.
|
|
6
|
+
*
|
|
7
|
+
* Platform URL is derived from the API base: api.minicor.com → app.minicor.com
|
|
8
|
+
*/
|
|
9
|
+
/** Derive platform base URL from API base URL. */
|
|
10
|
+
export declare function apiToPlatformBase(apiBase: string): string;
|
|
11
|
+
export declare class AgentServiceClient {
|
|
12
|
+
private platformBase;
|
|
13
|
+
private token;
|
|
14
|
+
constructor(apiBase: string, token: string);
|
|
15
|
+
private request;
|
|
16
|
+
listAgents(workspaceId?: number): Promise<any>;
|
|
17
|
+
getAgent(agentId: string): Promise<any>;
|
|
18
|
+
createAgent(data: {
|
|
19
|
+
name: string;
|
|
20
|
+
task: string;
|
|
21
|
+
vm_url: string;
|
|
22
|
+
workspace_id: number;
|
|
23
|
+
model?: string;
|
|
24
|
+
max_steps?: number;
|
|
25
|
+
mode?: "on-demand" | "scheduled" | "monitor";
|
|
26
|
+
service_id?: string;
|
|
27
|
+
watch_workflow_id?: number;
|
|
28
|
+
watch_workflow_name?: string;
|
|
29
|
+
recovery_task?: string;
|
|
30
|
+
slack_webhook_url?: string;
|
|
31
|
+
slack_channel?: string;
|
|
32
|
+
}): Promise<any>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=agent-service-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-service-client.d.ts","sourceRoot":"","sources":["../src/agent-service-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kDAAkD;AAClD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;YAK5B,OAAO;IAoCf,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM;IAS/B,QAAQ,CAAC,OAAO,EAAE,MAAM;IAIxB,WAAW,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;CAGF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent management client that routes through the Minicor platform proxy.
|
|
3
|
+
*
|
|
4
|
+
* /api/agents/[...path] proxies to the agent service and handles auth —
|
|
5
|
+
* the MCP sends its existing bearer token.
|
|
6
|
+
*
|
|
7
|
+
* Platform URL is derived from the API base: api.minicor.com → app.minicor.com
|
|
8
|
+
*/
|
|
9
|
+
/** Derive platform base URL from API base URL. */
|
|
10
|
+
export function apiToPlatformBase(apiBase) {
|
|
11
|
+
// https://api.minicor.com → https://app.minicor.com
|
|
12
|
+
// https://ca.api.minicor.com → https://ca.app.minicor.com
|
|
13
|
+
// http://localhost:8000 → http://localhost:3000 (dev)
|
|
14
|
+
if (apiBase.includes("localhost")) {
|
|
15
|
+
return apiBase.replace(/:\d+/, ":3000");
|
|
16
|
+
}
|
|
17
|
+
return apiBase.replace("api.", "app.");
|
|
18
|
+
}
|
|
19
|
+
export class AgentServiceClient {
|
|
20
|
+
platformBase;
|
|
21
|
+
token;
|
|
22
|
+
constructor(apiBase, token) {
|
|
23
|
+
this.platformBase = apiToPlatformBase(apiBase).replace(/\/+$/, "");
|
|
24
|
+
this.token = token;
|
|
25
|
+
}
|
|
26
|
+
async request(method, path, body, queryParams) {
|
|
27
|
+
let url = `${this.platformBase}/api/agents${path}`;
|
|
28
|
+
if (queryParams) {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
for (const [k, v] of Object.entries(queryParams)) {
|
|
31
|
+
if (v !== undefined && v !== null)
|
|
32
|
+
params.set(k, String(v));
|
|
33
|
+
}
|
|
34
|
+
const qs = params.toString();
|
|
35
|
+
if (qs)
|
|
36
|
+
url += `?${qs}`;
|
|
37
|
+
}
|
|
38
|
+
const res = await fetch(url, {
|
|
39
|
+
method,
|
|
40
|
+
headers: {
|
|
41
|
+
"Content-Type": "application/json",
|
|
42
|
+
Authorization: `Bearer ${this.token}`,
|
|
43
|
+
},
|
|
44
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
45
|
+
});
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const text = await res.text().catch(() => "");
|
|
48
|
+
throw new Error(`Agent Service ${method} ${path} failed (${res.status}): ${text}`);
|
|
49
|
+
}
|
|
50
|
+
if (res.status === 204)
|
|
51
|
+
return undefined;
|
|
52
|
+
return res.json();
|
|
53
|
+
}
|
|
54
|
+
async listAgents(workspaceId) {
|
|
55
|
+
return this.request("GET", "/agents", undefined, workspaceId ? { workspace_id: workspaceId } : undefined);
|
|
56
|
+
}
|
|
57
|
+
async getAgent(agentId) {
|
|
58
|
+
return this.request("GET", `/agents/${agentId}`);
|
|
59
|
+
}
|
|
60
|
+
async createAgent(data) {
|
|
61
|
+
return this.request("POST", "/agents", data);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=agent-service-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-service-client.js","sourceRoot":"","sources":["../src/agent-service-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kDAAkD;AAClD,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,oDAAoD;IACpD,0DAA0D;IAC1D,sDAAsD;IACtD,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,OAAO,kBAAkB;IACrB,YAAY,CAAS;IACrB,KAAK,CAAS;IAEtB,YAAY,OAAe,EAAE,KAAa;QACxC,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAc,EACd,IAAY,EACZ,IAAc,EACd,WAAyD;QAEzD,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,cAAc,IAAI,EAAE,CAAC;QACnD,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,EAAE;gBAAE,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QAC1B,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;aACtC;YACD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,iBAAiB,MAAM,IAAI,IAAI,YAAY,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAClE,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAc,CAAC;QAC9C,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,WAAoB;QACnC,OAAO,IAAI,CAAC,OAAO,CACjB,KAAK,EACL,SAAS,EACT,SAAS,EACT,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CACxD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAM,KAAK,EAAE,WAAW,OAAO,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAcjB;QACC,OAAO,IAAI,CAAC,OAAO,CAAM,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;CACF"}
|
package/dist/helpers.d.ts
CHANGED
|
@@ -20,6 +20,6 @@ export declare function safe<T>(fn: () => Promise<T>): Promise<{
|
|
|
20
20
|
text: string;
|
|
21
21
|
}[];
|
|
22
22
|
}>;
|
|
23
|
-
export declare const NOT_CONNECTED_VM = "No VM connected.
|
|
24
|
-
export declare function buildRpaProgram(pythonScript: string, pattern: "cloudflare_tunnel" | "channel" | "browser", flowId: string, stepName: string, stepDescription: string): string;
|
|
23
|
+
export declare const NOT_CONNECTED_VM = "No VM connected. Use vm_list to discover available VMs, then vm_connect with the vmId. Or provide a Cloudflare Tunnel URL directly to vm_connect.";
|
|
24
|
+
export declare function buildRpaProgram(pythonScript: string, pattern: "cloudflare_tunnel" | "channel" | "browser", flowId: string, stepName: string, stepDescription: string, expectedPreState?: string, expectedPostState?: string): string;
|
|
25
25
|
//# sourceMappingURL=helpers.d.ts.map
|
package/dist/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAE1C;AAED,wBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO;;;;;EAE/B;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM;;;;;EAE/B;AAED,wBAAsB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;;;;;GAMjD;AAED,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAE1C;AAED,wBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO;;;;;EAE/B;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM;;;;;EAE/B;AAED,wBAAsB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;;;;;GAMjD;AAED,eAAO,MAAM,gBAAgB,sJAAsJ,CAAC;AA0BpL,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,mBAAmB,GAAG,SAAS,GAAG,SAAS,EACpD,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,gBAAgB,CAAC,EAAE,MAAM,EACzB,iBAAiB,CAAC,EAAE,MAAM,GACzB,MAAM,CA6CR"}
|
package/dist/helpers.js
CHANGED
|
@@ -18,24 +18,44 @@ export async function safe(fn) {
|
|
|
18
18
|
return text(`Error: ${e.message}`);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
export const NOT_CONNECTED_VM = `No VM connected.
|
|
22
|
-
|
|
21
|
+
export const NOT_CONNECTED_VM = `No VM connected. Use vm_list to discover available VMs, then vm_connect with the vmId. Or provide a Cloudflare Tunnel URL directly to vm_connect.`;
|
|
22
|
+
function escapeJsonStringValue(value) {
|
|
23
|
+
return value
|
|
24
|
+
.replace(/\\/g, "\\\\")
|
|
25
|
+
.replace(/"/g, '\\"')
|
|
26
|
+
.replace(/\n/g, "\\n")
|
|
27
|
+
.replace(/\r/g, "\\r")
|
|
28
|
+
.replace(/\t/g, "\\t");
|
|
29
|
+
}
|
|
30
|
+
function buildStateLines(indent, expectedPreState, expectedPostState) {
|
|
31
|
+
const lines = [];
|
|
32
|
+
if (expectedPreState) {
|
|
33
|
+
lines.push(`${indent}"expectedPreState": "${escapeJsonStringValue(expectedPreState)}",`);
|
|
34
|
+
}
|
|
35
|
+
if (expectedPostState) {
|
|
36
|
+
lines.push(`${indent}"expectedPostState": "${escapeJsonStringValue(expectedPostState)}",`);
|
|
37
|
+
}
|
|
38
|
+
return lines.length > 0 ? "\n" + lines.join("\n") : "";
|
|
39
|
+
}
|
|
40
|
+
export function buildRpaProgram(pythonScript, pattern, flowId, stepName, stepDescription, expectedPreState, expectedPostState) {
|
|
23
41
|
const escaped = pythonScript.replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
42
|
+
const safeName = escapeJsonStringValue(stepName);
|
|
43
|
+
const safeDesc = escapeJsonStringValue(stepDescription);
|
|
44
|
+
const stateBlock = buildStateLines(" ", expectedPreState, expectedPostState);
|
|
24
45
|
if (pattern === "channel") {
|
|
46
|
+
const rpaStateBlock = buildStateLines(" ", expectedPreState, expectedPostState);
|
|
25
47
|
return `(data) => {
|
|
26
48
|
const pythonScript = \`
|
|
27
49
|
${escaped}
|
|
28
50
|
\`;
|
|
29
51
|
return {
|
|
30
52
|
"lam.rpa": {
|
|
31
|
-
"script": pythonScript
|
|
53
|
+
"script": pythonScript,${rpaStateBlock}
|
|
32
54
|
"channelId": "{{config.channelId}}"
|
|
33
55
|
}
|
|
34
56
|
};
|
|
35
57
|
}`;
|
|
36
58
|
}
|
|
37
|
-
// Browser scripts go to /execute/browser — MDS provides an isolated Chrome tab
|
|
38
|
-
// Desktop scripts go to /execute — no Chrome, just runs the script
|
|
39
59
|
const endpoint = pattern === "browser" ? "/execute/browser" : "/execute";
|
|
40
60
|
return `(data) => {
|
|
41
61
|
const pythonScript = \`
|
|
@@ -53,8 +73,8 @@ ${escaped}
|
|
|
53
73
|
"body": {
|
|
54
74
|
"flowId": "${flowId}",
|
|
55
75
|
"script": pythonScript,
|
|
56
|
-
"executionId": "1"
|
|
57
|
-
"step": { "id": "${flowId}", "name": "${
|
|
76
|
+
"executionId": "1",${stateBlock}
|
|
77
|
+
"step": { "id": "${flowId}", "name": "${safeName}", "description": "${safeDesc}", "versionId": "v1.0" }
|
|
58
78
|
}
|
|
59
79
|
}
|
|
60
80
|
};
|
package/dist/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,IAAI,CAAC,IAAa;IAChC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,EAAE,CAAC,IAAa;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAI,EAAoB;IAChD,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AA8DH,wBAAgB,UAAU,IAAI,MAAM,CAKnC"}
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,8 @@ import { register as registerSyncTools } from "./tools/sync-tools.js";
|
|
|
18
18
|
import { register as registerVm } from "./tools/vm.js";
|
|
19
19
|
import { register as registerVmRpa } from "./tools/vm-rpa.js";
|
|
20
20
|
import { register as registerTfa } from "./tools/tfa.js";
|
|
21
|
+
import { register as registerIssues } from "./tools/issues.js";
|
|
22
|
+
import { register as registerAgents } from "./tools/agents.js";
|
|
21
23
|
import { register as registerWorkflowGuide } from "./prompts/workflow-guide.js";
|
|
22
24
|
import { register as registerDebugExecution } from "./prompts/debug-execution.js";
|
|
23
25
|
import { register as registerBuildRpa } from "./prompts/build-rpa.js";
|
|
@@ -94,6 +96,10 @@ async function getValidToken() {
|
|
|
94
96
|
console.error("Warning: Token expired and refresh failed. Run `minicor-mcp-setup` to re-authenticate.");
|
|
95
97
|
return tokens.access_token;
|
|
96
98
|
}
|
|
99
|
+
const DEFAULT_VM_SERVICE_URL = "https://lam-vm-service-ernfuwetfa-uc.a.run.app";
|
|
100
|
+
function getVmServiceBase() {
|
|
101
|
+
return process.env.VM_MANAGER_API_URL || DEFAULT_VM_SERVICE_URL;
|
|
102
|
+
}
|
|
97
103
|
// ─── Resolve auth ────────────────────────────────────────────
|
|
98
104
|
async function resolveAuth() {
|
|
99
105
|
const stored = readStoredTokens();
|
|
@@ -118,6 +124,7 @@ function scheduleTokenRefresh() {
|
|
|
118
124
|
try {
|
|
119
125
|
const token = await getValidToken();
|
|
120
126
|
client = new LaminarClient({ type: "bearer", token }, getApiBase());
|
|
127
|
+
currentToken = token;
|
|
121
128
|
console.error("Token auto-refreshed, client updated.");
|
|
122
129
|
}
|
|
123
130
|
catch (e) {
|
|
@@ -142,11 +149,14 @@ function registerUnauthenticated() {
|
|
|
142
149
|
}));
|
|
143
150
|
}
|
|
144
151
|
// ─── Register all tools and prompts ──────────────────────────
|
|
152
|
+
let currentToken = "";
|
|
145
153
|
function registerAll() {
|
|
146
154
|
const deps = {
|
|
147
155
|
server,
|
|
148
156
|
client: () => client,
|
|
149
157
|
getApiBase,
|
|
158
|
+
getVmServiceBase,
|
|
159
|
+
getAuthToken: () => currentToken,
|
|
150
160
|
};
|
|
151
161
|
registerCore(deps);
|
|
152
162
|
registerWorkflowOps(deps);
|
|
@@ -155,6 +165,8 @@ function registerAll() {
|
|
|
155
165
|
registerVm(deps);
|
|
156
166
|
registerVmRpa(deps);
|
|
157
167
|
registerTfa(deps);
|
|
168
|
+
registerIssues(deps);
|
|
169
|
+
registerAgents(deps);
|
|
158
170
|
registerWorkflowGuide(deps);
|
|
159
171
|
registerDebugExecution(deps);
|
|
160
172
|
registerBuildRpa(deps);
|
|
@@ -169,6 +181,7 @@ async function main() {
|
|
|
169
181
|
}
|
|
170
182
|
else {
|
|
171
183
|
client = new LaminarClient(authResult.auth, authResult.baseUrl);
|
|
184
|
+
currentToken = authResult.auth.token;
|
|
172
185
|
scheduleTokenRefresh();
|
|
173
186
|
registerAll();
|
|
174
187
|
}
|