@monoes/monomindcli 1.18.5 → 1.18.6
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/package.json +6 -1
- package/dist/src/__tests__/browse-adapters.test.d.ts +0 -2
- package/dist/src/__tests__/browse-adapters.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-adapters.test.js +0 -51
- package/dist/src/__tests__/browse-adapters.test.js.map +0 -1
- package/dist/src/__tests__/browse-analyzer.test.d.ts +0 -2
- package/dist/src/__tests__/browse-analyzer.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-analyzer.test.js +0 -68
- package/dist/src/__tests__/browse-analyzer.test.js.map +0 -1
- package/dist/src/__tests__/browse-builtin-handlers.test.d.ts +0 -2
- package/dist/src/__tests__/browse-builtin-handlers.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-builtin-handlers.test.js +0 -139
- package/dist/src/__tests__/browse-builtin-handlers.test.js.map +0 -1
- package/dist/src/__tests__/browse-cdp.test.d.ts +0 -2
- package/dist/src/__tests__/browse-cdp.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-cdp.test.js +0 -169
- package/dist/src/__tests__/browse-cdp.test.js.map +0 -1
- package/dist/src/__tests__/browse-dashboard.test.d.ts +0 -2
- package/dist/src/__tests__/browse-dashboard.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-dashboard.test.js +0 -179
- package/dist/src/__tests__/browse-dashboard.test.js.map +0 -1
- package/dist/src/__tests__/browse-engine.test.d.ts +0 -2
- package/dist/src/__tests__/browse-engine.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-engine.test.js +0 -122
- package/dist/src/__tests__/browse-engine.test.js.map +0 -1
- package/dist/src/__tests__/browse-expression.test.d.ts +0 -2
- package/dist/src/__tests__/browse-expression.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-expression.test.js +0 -54
- package/dist/src/__tests__/browse-expression.test.js.map +0 -1
- package/dist/src/__tests__/browse-store.test.d.ts +0 -2
- package/dist/src/__tests__/browse-store.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-store.test.js +0 -99
- package/dist/src/__tests__/browse-store.test.js.map +0 -1
- package/dist/src/__tests__/browse-workflow-types.test.d.ts +0 -2
- package/dist/src/__tests__/browse-workflow-types.test.d.ts.map +0 -1
- package/dist/src/__tests__/browse-workflow-types.test.js +0 -33
- package/dist/src/__tests__/browse-workflow-types.test.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -66,6 +66,9 @@
|
|
|
66
66
|
},
|
|
67
67
|
"files": [
|
|
68
68
|
"dist",
|
|
69
|
+
"!dist/**/*.test.js",
|
|
70
|
+
"!dist/**/*.test.d.ts",
|
|
71
|
+
"!dist/**/__tests__/**",
|
|
69
72
|
"bin",
|
|
70
73
|
".claude",
|
|
71
74
|
"scripts",
|
|
@@ -79,6 +82,8 @@
|
|
|
79
82
|
"ws": "^8.21.0",
|
|
80
83
|
"@noble/ed25519": "^2.1.0",
|
|
81
84
|
"@monoes/monobrowse": "^1.0.1",
|
|
85
|
+
"zod": "^3.25.0",
|
|
86
|
+
"yaml": "^2.8.0",
|
|
82
87
|
"@monoes/monograph": "1.2.10"
|
|
83
88
|
},
|
|
84
89
|
"optionalDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-adapters.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-adapters.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// src/__tests__/browse-adapters.test.ts
|
|
2
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
-
import { getAdapter, adapters } from '@monoes/monobrowse';
|
|
4
|
-
function mockPage(isLoggedIn, username = 'testuser') {
|
|
5
|
-
return {
|
|
6
|
-
evaluate: vi.fn().mockImplementation((expr) => {
|
|
7
|
-
if (expr.includes('querySelector'))
|
|
8
|
-
return Promise.resolve(isLoggedIn ? true : false);
|
|
9
|
-
return Promise.resolve(username);
|
|
10
|
-
}),
|
|
11
|
-
url: vi.fn().mockResolvedValue('https://example.com'),
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
describe('adapter registry', () => {
|
|
15
|
-
it('has all 6 platforms', () => {
|
|
16
|
-
expect(adapters.size).toBe(6);
|
|
17
|
-
for (const p of ['linkedin', 'instagram', 'x', 'gemini', 'google', 'microsoft']) {
|
|
18
|
-
expect(adapters.has(p)).toBe(true);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
it('getAdapter throws for unknown platform', () => {
|
|
22
|
-
expect(() => getAdapter('myspace')).toThrow('Unknown platform');
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
describe('each adapter', () => {
|
|
26
|
-
const platforms = ['linkedin', 'instagram', 'x', 'gemini', 'google', 'microsoft'];
|
|
27
|
-
for (const platform of platforms) {
|
|
28
|
-
describe(platform, () => {
|
|
29
|
-
const adapter = getAdapter(platform);
|
|
30
|
-
it('has required fields', () => {
|
|
31
|
-
expect(typeof adapter.platform).toBe('string');
|
|
32
|
-
expect(adapter.baseURL).toMatch(/^https?:\/\//);
|
|
33
|
-
expect(Array.isArray(adapter.reservedPaths)).toBe(true);
|
|
34
|
-
expect(adapter.reservedPaths.length).toBeGreaterThan(0);
|
|
35
|
-
expect(typeof adapter.loginURL()).toBe('string');
|
|
36
|
-
});
|
|
37
|
-
it('isLoggedIn returns boolean', async () => {
|
|
38
|
-
const page = mockPage(true);
|
|
39
|
-
const result = await adapter.isLoggedIn(page);
|
|
40
|
-
expect(typeof result).toBe('boolean');
|
|
41
|
-
});
|
|
42
|
-
it('extractUsername returns string', async () => {
|
|
43
|
-
const page = mockPage(true);
|
|
44
|
-
page.evaluate = vi.fn().mockResolvedValue('johndoe');
|
|
45
|
-
const username = await adapter.extractUsername(page);
|
|
46
|
-
expect(typeof username).toBe('string');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
//# sourceMappingURL=browse-adapters.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-adapters.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-adapters.test.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG1D,SAAS,QAAQ,CAAC,UAAmB,EAAE,QAAQ,GAAG,UAAU;IAC1D,OAAO;QACL,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,IAAY,EAAE,EAAE;YACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;gBAAE,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACtF,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC;QACF,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,qBAAqB,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;YAChF,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;IAE3F,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,MAAM,OAAO,GAAG,UAAU,CAAC,QAAkB,CAAC,CAAC;YAE/C,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;gBAC7B,MAAM,CAAC,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC/C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAChD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBACxD,MAAM,CAAC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;gBAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;gBAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;gBACrD,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-analyzer.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-analyzer.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { EventEmitter } from 'events';
|
|
3
|
-
// Mock child_process.spawn so tests don't invoke the real claude CLI
|
|
4
|
-
vi.mock('child_process', async (importOriginal) => {
|
|
5
|
-
const actual = await importOriginal();
|
|
6
|
-
return { ...actual, spawn: vi.fn() };
|
|
7
|
-
});
|
|
8
|
-
async function makeSpawnMock(stdout, exitCode = 0) {
|
|
9
|
-
const { spawn } = vi.mocked(await import('child_process'));
|
|
10
|
-
spawn.mockImplementationOnce(() => {
|
|
11
|
-
const proc = new EventEmitter();
|
|
12
|
-
proc.stdout = new EventEmitter();
|
|
13
|
-
proc.stderr = new EventEmitter();
|
|
14
|
-
proc.kill = vi.fn();
|
|
15
|
-
setTimeout(() => {
|
|
16
|
-
proc.stdout.emit('data', Buffer.from(stdout));
|
|
17
|
-
proc.emit('close', exitCode);
|
|
18
|
-
}, 0);
|
|
19
|
-
return proc;
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
const VALID_ACTION_DEF = {
|
|
23
|
-
id: 'linkedin:comment_post',
|
|
24
|
-
platform: 'linkedin',
|
|
25
|
-
name: 'Comment on Post',
|
|
26
|
-
params: ['post_url', 'text'],
|
|
27
|
-
steps: [
|
|
28
|
-
{ type: 'navigate', url: '{{params.post_url}}' },
|
|
29
|
-
{ type: 'find', selectors: ['.comment-box'], as: 'box' },
|
|
30
|
-
{ type: 'click', target: '{{box}}' },
|
|
31
|
-
{ type: 'type', target: '{{box}}', text: '{{params.text}}', humanDelay: true },
|
|
32
|
-
{ type: 'wait', condition: 'network_idle', timeout: 3000 },
|
|
33
|
-
],
|
|
34
|
-
};
|
|
35
|
-
function mockPage(url = 'https://linkedin.com/feed', title = 'LinkedIn') {
|
|
36
|
-
return {
|
|
37
|
-
url: vi.fn().mockResolvedValue(url),
|
|
38
|
-
evaluate: vi.fn().mockImplementation((expr) => {
|
|
39
|
-
if (expr === 'document.title')
|
|
40
|
-
return Promise.resolve(title);
|
|
41
|
-
return Promise.resolve('[]');
|
|
42
|
-
}),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
describe('analyzePageForAction', () => {
|
|
46
|
-
let analyzePageForAction;
|
|
47
|
-
beforeEach(async () => {
|
|
48
|
-
vi.resetModules();
|
|
49
|
-
const mod = await import('@monoes/monobrowse');
|
|
50
|
-
analyzePageForAction = mod.analyzePageForAction;
|
|
51
|
-
}, 20000); // monolean: re-importing the workspace package can exceed the 10s default under full-suite parallel load
|
|
52
|
-
it('returns a valid ActionDef from mocked claude --print response', async () => {
|
|
53
|
-
await makeSpawnMock(JSON.stringify(VALID_ACTION_DEF));
|
|
54
|
-
const result = await analyzePageForAction(mockPage(), 'comment on a LinkedIn post');
|
|
55
|
-
expect(result.id).toBe('linkedin:comment_post');
|
|
56
|
-
expect(result.steps).toHaveLength(5);
|
|
57
|
-
expect(result.params).toContain('text');
|
|
58
|
-
});
|
|
59
|
-
it('throws on invalid JSON from claude', async () => {
|
|
60
|
-
await makeSpawnMock('not json at all');
|
|
61
|
-
await expect(analyzePageForAction(mockPage(), 'test')).rejects.toThrow('invalid JSON');
|
|
62
|
-
});
|
|
63
|
-
it('throws when ActionDef is missing id', async () => {
|
|
64
|
-
await makeSpawnMock(JSON.stringify({ steps: [] }));
|
|
65
|
-
await expect(analyzePageForAction(mockPage(), 'test')).rejects.toThrow('invalid ActionDef');
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
//# sourceMappingURL=browse-analyzer.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-analyzer.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-analyzer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-builtin-handlers.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-builtin-handlers.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
// Mock fs/promises before importing the module under test
|
|
3
|
-
vi.mock('node:fs/promises', () => ({
|
|
4
|
-
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
5
|
-
readFile: vi.fn().mockRejectedValue(new Error('no file')),
|
|
6
|
-
mkdir: vi.fn().mockResolvedValue(undefined),
|
|
7
|
-
chmod: vi.fn().mockResolvedValue(undefined),
|
|
8
|
-
}));
|
|
9
|
-
vi.mock('node:fs', () => ({
|
|
10
|
-
existsSync: vi.fn().mockReturnValue(false),
|
|
11
|
-
}));
|
|
12
|
-
// Mock the browser module so gemini_image CDP path returns null immediately
|
|
13
|
-
vi.mock('../browser/index.js', () => ({
|
|
14
|
-
connectToTarget: vi.fn().mockRejectedValue(new Error('no browser')),
|
|
15
|
-
setCookies: vi.fn(),
|
|
16
|
-
openUrl: vi.fn(),
|
|
17
|
-
findByRole: vi.fn(),
|
|
18
|
-
findBySelector: vi.fn(),
|
|
19
|
-
clickElement: vi.fn(),
|
|
20
|
-
fillElement: vi.fn(),
|
|
21
|
-
pressKey: vi.fn(),
|
|
22
|
-
evaluateJs: vi.fn(),
|
|
23
|
-
getCookies: vi.fn().mockResolvedValue([]),
|
|
24
|
-
getCurrentUrl: vi.fn().mockResolvedValue(''),
|
|
25
|
-
captureScreenshot: vi.fn().mockResolvedValue(null),
|
|
26
|
-
}));
|
|
27
|
-
import { createBuiltinHandlers } from '@monoes/monobrowse';
|
|
28
|
-
import * as fsMock from 'node:fs/promises';
|
|
29
|
-
function makeItem(data = {}) {
|
|
30
|
-
return { data };
|
|
31
|
-
}
|
|
32
|
-
describe('createBuiltinHandlers', () => {
|
|
33
|
-
it('returns a Map with the expected handler keys', () => {
|
|
34
|
-
const handlers = createBuiltinHandlers();
|
|
35
|
-
expect(handlers).toBeInstanceOf(Map);
|
|
36
|
-
expect(handlers.has('action.http')).toBe(true);
|
|
37
|
-
expect(handlers.has('action.save_file')).toBe(true);
|
|
38
|
-
expect(handlers.has('action.log')).toBe(true);
|
|
39
|
-
expect(handlers.has('action.gemini_image')).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe('action.save_file', () => {
|
|
43
|
-
let handlers;
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
vi.clearAllMocks();
|
|
46
|
-
// existsSync stays false — no sessions file
|
|
47
|
-
handlers = createBuiltinHandlers();
|
|
48
|
-
});
|
|
49
|
-
it('writes a file for a safe relative path', async () => {
|
|
50
|
-
const handler = handlers.get('action.save_file');
|
|
51
|
-
const items = [makeItem({ hello: 'world' })];
|
|
52
|
-
const result = await handler(items, { path: 'output.txt' });
|
|
53
|
-
expect(fsMock.writeFile).toHaveBeenCalled();
|
|
54
|
-
expect(result[0].data.savedPath).toMatch(/output\.txt$/);
|
|
55
|
-
});
|
|
56
|
-
it('throws "Path traversal blocked" for a path that escapes cwd', async () => {
|
|
57
|
-
const handler = handlers.get('action.save_file');
|
|
58
|
-
const items = [makeItem()];
|
|
59
|
-
await expect(handler(items, { path: '../../etc/passwd' })).rejects.toThrow('Path traversal blocked');
|
|
60
|
-
});
|
|
61
|
-
it('writes binary content when item.binaryBase64 is set', async () => {
|
|
62
|
-
const handler = handlers.get('action.save_file');
|
|
63
|
-
const binaryItem = { data: {}, binaryBase64: Buffer.from('abc').toString('base64') };
|
|
64
|
-
const result = await handler([binaryItem], { path: 'img.png' });
|
|
65
|
-
expect(fsMock.writeFile).toHaveBeenCalled();
|
|
66
|
-
const [, content] = vi.mocked(fsMock.writeFile).mock.calls[0];
|
|
67
|
-
expect(Buffer.isBuffer(content)).toBe(true);
|
|
68
|
-
expect(result[0].data.savedPath).toMatch(/img\.png$/);
|
|
69
|
-
});
|
|
70
|
-
it('uses config.content when no field is provided', async () => {
|
|
71
|
-
const handler = handlers.get('action.save_file');
|
|
72
|
-
const items = [makeItem()];
|
|
73
|
-
const result = await handler(items, { path: 'out.txt', content: 'hello content' });
|
|
74
|
-
const [, written] = vi.mocked(fsMock.writeFile).mock.calls[0];
|
|
75
|
-
expect(written).toBe('hello content');
|
|
76
|
-
expect(result[0].data.savedPath).toMatch(/out\.txt$/);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
describe('action.gemini_image', () => {
|
|
80
|
-
let handlers;
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
vi.clearAllMocks();
|
|
83
|
-
handlers = createBuiltinHandlers();
|
|
84
|
-
});
|
|
85
|
-
it('falls back to mock mode when browser and API key are unavailable', async () => {
|
|
86
|
-
const handler = handlers.get('action.gemini_image');
|
|
87
|
-
// No GEMINI_API_KEY set, browser import throws — mock mode
|
|
88
|
-
delete process.env['GEMINI_API_KEY'];
|
|
89
|
-
delete process.env['GOOGLE_API_KEY'];
|
|
90
|
-
const items = [makeItem({ prompt: 'a beautiful sunset' })];
|
|
91
|
-
const result = await handler(items, { prompt: 'a beautiful sunset', cdpPort: 19999 });
|
|
92
|
-
expect(result[0].data.mockMode).toBe(true);
|
|
93
|
-
expect(result[0].data.prompt).toBe('a beautiful sunset');
|
|
94
|
-
});
|
|
95
|
-
it('throws "Path traversal blocked" for outputPath outside cwd', async () => {
|
|
96
|
-
const handler = handlers.get('action.gemini_image');
|
|
97
|
-
delete process.env['GEMINI_API_KEY'];
|
|
98
|
-
delete process.env['GOOGLE_API_KEY'];
|
|
99
|
-
const items = [makeItem()];
|
|
100
|
-
await expect(handler(items, { prompt: 'test', outputPath: '../../evil.png', cdpPort: 19999 })).rejects.toThrow('Path traversal blocked');
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe('action.http', () => {
|
|
104
|
-
let handlers;
|
|
105
|
-
const originalFetch = globalThis.fetch;
|
|
106
|
-
beforeEach(() => {
|
|
107
|
-
handlers = createBuiltinHandlers();
|
|
108
|
-
});
|
|
109
|
-
afterEach(() => {
|
|
110
|
-
globalThis.fetch = originalFetch;
|
|
111
|
-
});
|
|
112
|
-
it('fetches a URL and stores response in item.data.response', async () => {
|
|
113
|
-
const mockFetch = vi.fn().mockResolvedValue({
|
|
114
|
-
ok: true,
|
|
115
|
-
status: 200,
|
|
116
|
-
text: async () => JSON.stringify({ success: true }),
|
|
117
|
-
});
|
|
118
|
-
globalThis.fetch = mockFetch;
|
|
119
|
-
const handler = handlers.get('action.http');
|
|
120
|
-
const items = [makeItem()];
|
|
121
|
-
const result = await handler(items, { url: 'https://example.com/api', method: 'GET' });
|
|
122
|
-
expect(mockFetch).toHaveBeenCalledWith('https://example.com/api', expect.objectContaining({ method: 'GET' }));
|
|
123
|
-
expect(result[0].data.response.statusCode).toBe(200);
|
|
124
|
-
expect(result[0].data.response.json).toEqual({ success: true });
|
|
125
|
-
});
|
|
126
|
-
it('uses a custom responseField when specified', async () => {
|
|
127
|
-
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
128
|
-
ok: true,
|
|
129
|
-
status: 201,
|
|
130
|
-
text: async () => 'created',
|
|
131
|
-
});
|
|
132
|
-
const handler = handlers.get('action.http');
|
|
133
|
-
const items = [makeItem()];
|
|
134
|
-
const result = await handler(items, { url: 'https://example.com', responseField: 'myResult' });
|
|
135
|
-
expect(result[0].data.myResult).toBeDefined();
|
|
136
|
-
expect(result[0].data.myResult.statusCode).toBe(201);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
//# sourceMappingURL=browse-builtin-handlers.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-builtin-handlers.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-builtin-handlers.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-cdp.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-cdp.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
// ---------------------------------------------------------------------------
|
|
3
|
-
// Fake WebSocket — mimics the Node.js EventEmitter-style API that 'ws' uses
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
class FakeWS {
|
|
6
|
-
readyState = 1; // OPEN
|
|
7
|
-
sent = [];
|
|
8
|
-
_handlers = {};
|
|
9
|
-
on(event, fn) {
|
|
10
|
-
if (!this._handlers[event])
|
|
11
|
-
this._handlers[event] = [];
|
|
12
|
-
this._handlers[event].push(fn);
|
|
13
|
-
return this;
|
|
14
|
-
}
|
|
15
|
-
send(data, cb) {
|
|
16
|
-
this.sent.push(data);
|
|
17
|
-
cb?.();
|
|
18
|
-
}
|
|
19
|
-
close() {
|
|
20
|
-
this.emit('close');
|
|
21
|
-
}
|
|
22
|
-
emit(event, ...args) {
|
|
23
|
-
for (const fn of this._handlers[event] ?? [])
|
|
24
|
-
fn(...args);
|
|
25
|
-
}
|
|
26
|
-
/** Simulate a message arriving from the browser */
|
|
27
|
-
simulateMessage(obj) {
|
|
28
|
-
this.emit('message', JSON.stringify(obj));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
// Module-level reference so test helpers can access the last FakeWS instance
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
let fakeWsInstance = null;
|
|
35
|
-
// We need WebSocket to be constructable. Use vi.fn() and expose a class-like
|
|
36
|
-
// constructor that captures the instance.
|
|
37
|
-
function FakeWebSocket(_url) {
|
|
38
|
-
fakeWsInstance = new FakeWS();
|
|
39
|
-
Object.assign(this, fakeWsInstance);
|
|
40
|
-
// Proxy the FakeWS methods onto `this`
|
|
41
|
-
for (const key of Object.getOwnPropertyNames(FakeWS.prototype)) {
|
|
42
|
-
if (key !== 'constructor') {
|
|
43
|
-
this[key] = fakeWsInstance[key].bind(fakeWsInstance);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// Also expose sent and emit directly on `this`
|
|
47
|
-
Object.defineProperty(this, 'sent', {
|
|
48
|
-
get: () => fakeWsInstance.sent,
|
|
49
|
-
configurable: true,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
vi.mock('ws', () => ({
|
|
53
|
-
WebSocket: FakeWebSocket,
|
|
54
|
-
}));
|
|
55
|
-
import { CdpClient } from '@monoes/monobrowse';
|
|
56
|
-
// ---------------------------------------------------------------------------
|
|
57
|
-
// Helpers
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
function openClient() {
|
|
60
|
-
const client = new CdpClient();
|
|
61
|
-
client.connect('ws://localhost:9222/devtools/page/abc');
|
|
62
|
-
const ws = fakeWsInstance;
|
|
63
|
-
ws.emit('open');
|
|
64
|
-
return { client, ws };
|
|
65
|
-
}
|
|
66
|
-
async function connectedClient() {
|
|
67
|
-
const { client, ws } = openClient();
|
|
68
|
-
await Promise.resolve();
|
|
69
|
-
return { client, ws };
|
|
70
|
-
}
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
72
|
-
// Tests
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
describe('CdpClient', () => {
|
|
75
|
-
beforeEach(() => {
|
|
76
|
-
fakeWsInstance = null;
|
|
77
|
-
vi.clearAllMocks();
|
|
78
|
-
});
|
|
79
|
-
it('connects and resolves when the WebSocket opens', async () => {
|
|
80
|
-
const client = new CdpClient();
|
|
81
|
-
const p = client.connect('ws://localhost:9222/devtools/page/abc');
|
|
82
|
-
fakeWsInstance.emit('open');
|
|
83
|
-
await expect(p).resolves.toBeUndefined();
|
|
84
|
-
expect(client.isConnected()).toBe(true);
|
|
85
|
-
});
|
|
86
|
-
it('rejects when the WebSocket emits an error before opening', async () => {
|
|
87
|
-
const client = new CdpClient();
|
|
88
|
-
const p = client.connect('ws://localhost:9222/devtools/page/abc');
|
|
89
|
-
const err = new Error('ECONNREFUSED');
|
|
90
|
-
fakeWsInstance.emit('error', err);
|
|
91
|
-
await expect(p).rejects.toThrow('ECONNREFUSED');
|
|
92
|
-
});
|
|
93
|
-
it('sends a command and resolves with the response result', async () => {
|
|
94
|
-
const { client, ws } = await connectedClient();
|
|
95
|
-
const sendPromise = client.send('Runtime.evaluate', { expression: '1+1' });
|
|
96
|
-
const sent = JSON.parse(ws.sent[0]);
|
|
97
|
-
expect(sent.method).toBe('Runtime.evaluate');
|
|
98
|
-
ws.simulateMessage({ id: sent.id, result: { value: 2 } });
|
|
99
|
-
const result = await sendPromise;
|
|
100
|
-
expect(result.value).toBe(2);
|
|
101
|
-
});
|
|
102
|
-
it('rejects a command when the response contains a CDP error', async () => {
|
|
103
|
-
const { client, ws } = await connectedClient();
|
|
104
|
-
const sendPromise = client.send('DOM.getDocument');
|
|
105
|
-
const sent = JSON.parse(ws.sent[0]);
|
|
106
|
-
ws.simulateMessage({ id: sent.id, error: { code: -32000, message: 'Not found' } });
|
|
107
|
-
await expect(sendPromise).rejects.toThrow('CDP error -32000: Not found');
|
|
108
|
-
});
|
|
109
|
-
it('rejects when not connected', async () => {
|
|
110
|
-
const client = new CdpClient();
|
|
111
|
-
await expect(client.send('Page.navigate')).rejects.toThrow('CDP not connected');
|
|
112
|
-
});
|
|
113
|
-
it('enforces 1000 in-flight command cap', async () => {
|
|
114
|
-
const { client, ws } = await connectedClient();
|
|
115
|
-
// Override send to avoid callbacks so commands stay pending
|
|
116
|
-
vi.spyOn(ws, 'send').mockImplementation((data) => {
|
|
117
|
-
ws.sent.push(data);
|
|
118
|
-
});
|
|
119
|
-
// Fill up to 1000 pending
|
|
120
|
-
for (let i = 0; i < 1000; i++) {
|
|
121
|
-
client.send('Page.dummy').catch(() => { });
|
|
122
|
-
}
|
|
123
|
-
// 1001st command should be rejected immediately
|
|
124
|
-
await expect(client.send('Page.overflow')).rejects.toThrow('queue full');
|
|
125
|
-
});
|
|
126
|
-
it('rejects all pending commands when the connection closes', async () => {
|
|
127
|
-
const { client, ws } = await connectedClient();
|
|
128
|
-
vi.spyOn(ws, 'send').mockImplementation((data) => {
|
|
129
|
-
ws.sent.push(data);
|
|
130
|
-
// no callback — keeps command in-flight
|
|
131
|
-
});
|
|
132
|
-
const pendingPromise = client.send('Page.navigate');
|
|
133
|
-
ws.emit('close');
|
|
134
|
-
await expect(pendingPromise).rejects.toThrow('CDP connection closed');
|
|
135
|
-
expect(client.isConnected()).toBe(false);
|
|
136
|
-
});
|
|
137
|
-
it('fires event listeners when a CDP event arrives', async () => {
|
|
138
|
-
const { client, ws } = await connectedClient();
|
|
139
|
-
const listener = vi.fn();
|
|
140
|
-
client.on('Page.loadEventFired', listener);
|
|
141
|
-
ws.simulateMessage({ method: 'Page.loadEventFired', params: { timestamp: 1.23 } });
|
|
142
|
-
expect(listener).toHaveBeenCalledWith({ timestamp: 1.23 }, undefined);
|
|
143
|
-
});
|
|
144
|
-
it('enforces 100 listener cap per event', async () => {
|
|
145
|
-
const { client } = await connectedClient();
|
|
146
|
-
for (let i = 0; i < 100; i++) {
|
|
147
|
-
client.on('Page.frameNavigated', vi.fn());
|
|
148
|
-
}
|
|
149
|
-
expect(() => client.on('Page.frameNavigated', vi.fn())).toThrow('CDP event listener limit reached');
|
|
150
|
-
});
|
|
151
|
-
it('close() rejects pending commands and disconnects', async () => {
|
|
152
|
-
const { client, ws } = await connectedClient();
|
|
153
|
-
vi.spyOn(ws, 'send').mockImplementation((data) => {
|
|
154
|
-
ws.sent.push(data);
|
|
155
|
-
});
|
|
156
|
-
const p = client.send('Network.enable');
|
|
157
|
-
client.close();
|
|
158
|
-
await expect(p).rejects.toThrow('CDP connection closed');
|
|
159
|
-
expect(client.isConnected()).toBe(false);
|
|
160
|
-
});
|
|
161
|
-
it('once() resolves on the first matching event', async () => {
|
|
162
|
-
const { client, ws } = await connectedClient();
|
|
163
|
-
const oncePromise = client.once('Page.loadEventFired');
|
|
164
|
-
ws.simulateMessage({ method: 'Page.loadEventFired', params: { timestamp: 99 } });
|
|
165
|
-
const params = await oncePromise;
|
|
166
|
-
expect(params).toEqual({ timestamp: 99 });
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
//# sourceMappingURL=browse-cdp.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-cdp.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-cdp.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-dashboard.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-dashboard.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
-
import { startDashboard, getDashboard } from '@monoes/monobrowse';
|
|
3
|
-
import { WebSocket } from 'ws';
|
|
4
|
-
const PORT = 14242; // Use non-conflicting test port
|
|
5
|
-
const SSE_PORT = 14243; // Separate port for SSE streaming tests
|
|
6
|
-
afterEach(() => {
|
|
7
|
-
getDashboard()?.close();
|
|
8
|
-
});
|
|
9
|
-
function makeEvent(overrides = {}) {
|
|
10
|
-
return {
|
|
11
|
-
runId: 'run-1',
|
|
12
|
-
playbookId: 'wf-1',
|
|
13
|
-
playbookName: 'Test WF',
|
|
14
|
-
nodeId: 'node-1',
|
|
15
|
-
nodeName: 'Test Node',
|
|
16
|
-
eventType: 'step_completed',
|
|
17
|
-
timestamp: Date.now(),
|
|
18
|
-
...overrides,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
describe('startDashboard', () => {
|
|
22
|
-
it('returns a dashboard server instance', async () => {
|
|
23
|
-
const dash = startDashboard(PORT);
|
|
24
|
-
expect(dash).toBeDefined();
|
|
25
|
-
expect(dash.port).toBe(PORT);
|
|
26
|
-
});
|
|
27
|
-
it('returns the same instance on repeated calls', async () => {
|
|
28
|
-
const a = startDashboard(PORT);
|
|
29
|
-
const b = startDashboard(PORT);
|
|
30
|
-
expect(a).toBe(b);
|
|
31
|
-
});
|
|
32
|
-
it('serves HTML at GET /', async () => {
|
|
33
|
-
startDashboard(PORT);
|
|
34
|
-
const res = await fetch(`http://localhost:${PORT}/`);
|
|
35
|
-
expect(res.status).toBe(200);
|
|
36
|
-
expect(res.headers.get('content-type')).toContain('text/html');
|
|
37
|
-
const body = await res.text();
|
|
38
|
-
expect(body).toContain('monomind');
|
|
39
|
-
});
|
|
40
|
-
it('GET /runs returns JSON array', async () => {
|
|
41
|
-
const dash = startDashboard(PORT);
|
|
42
|
-
const run = { id: 'r1', playbookId: 'wf', playbookName: 'WF', status: 'completed', startedAt: Date.now(), itemsProcessed: 1, itemsTotal: 1 };
|
|
43
|
-
dash.addRunRecord(run);
|
|
44
|
-
const res = await fetch(`http://localhost:${PORT}/runs`);
|
|
45
|
-
expect(res.status).toBe(200);
|
|
46
|
-
const body = await res.json();
|
|
47
|
-
expect(body.some(r => r.id === 'r1')).toBe(true);
|
|
48
|
-
});
|
|
49
|
-
it('POST /stop/:runId marks run as stop-requested', async () => {
|
|
50
|
-
const dash = startDashboard(PORT);
|
|
51
|
-
const res = await fetch(`http://localhost:${PORT}/stop/run-abc`, { method: 'POST' });
|
|
52
|
-
expect(res.status).toBe(200);
|
|
53
|
-
expect(dash.isStopRequested('run-abc')).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
it('isStopRequested returns false for unknown runId', () => {
|
|
56
|
-
const dash = startDashboard(PORT);
|
|
57
|
-
expect(dash.isStopRequested('nonexistent')).toBe(false);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
// SSE / WebSocket streaming tests
|
|
62
|
-
//
|
|
63
|
-
// The dashboard uses WebSocket (via 'ws') when the package is available, and
|
|
64
|
-
// falls back to Server-Sent Events when it is not. Since 'ws' IS installed in
|
|
65
|
-
// this repo the server runs in WebSocket mode. We test the streaming path
|
|
66
|
-
// (broadcast + ?dir= filter) through the WebSocket interface so the tests are
|
|
67
|
-
// consistent regardless of environment.
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
/**
|
|
70
|
-
* Open a WebSocket to the dashboard, wait for the initial 'history' message,
|
|
71
|
-
* then return a helper that collects subsequent messages.
|
|
72
|
-
*/
|
|
73
|
-
function connectWs(port, dir) {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
const url = dir ? `ws://127.0.0.1:${port}/?dir=${encodeURIComponent(dir)}` : `ws://127.0.0.1:${port}/`;
|
|
76
|
-
const ws = new WebSocket(url);
|
|
77
|
-
const messages = [];
|
|
78
|
-
ws.on('open', () => {
|
|
79
|
-
// history message arrives; resolve after we have it
|
|
80
|
-
ws.on('message', (data) => {
|
|
81
|
-
const parsed = JSON.parse(data.toString());
|
|
82
|
-
messages.push(parsed);
|
|
83
|
-
if (messages.length === 1 && parsed.type === 'history') {
|
|
84
|
-
resolve({ ws, messages, close: () => ws.close() });
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
ws.on('error', reject);
|
|
89
|
-
setTimeout(() => reject(new Error('WS connect timeout')), 3000);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
describe('broadcast via WebSocket', () => {
|
|
93
|
-
it('delivers events to connected clients', async () => {
|
|
94
|
-
const dash = startDashboard(PORT);
|
|
95
|
-
// Wait a tick for the server to be ready
|
|
96
|
-
await new Promise(r => setTimeout(r, 50));
|
|
97
|
-
const { ws, messages, close } = await connectWs(PORT);
|
|
98
|
-
try {
|
|
99
|
-
// Wait for initial history message, then broadcast
|
|
100
|
-
dash.broadcast(makeEvent({ eventType: 'step_completed', nodeId: 'node-broadcast-1' }));
|
|
101
|
-
await new Promise(r => setTimeout(r, 100));
|
|
102
|
-
const events = messages.filter((m) => m.eventType !== undefined);
|
|
103
|
-
expect(events.length).toBeGreaterThan(0);
|
|
104
|
-
expect(events[0].nodeId).toBe('node-broadcast-1');
|
|
105
|
-
}
|
|
106
|
-
finally {
|
|
107
|
-
close();
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
it('?dir= filter — client with matching dir receives event', async () => {
|
|
111
|
-
const dash = startDashboard(PORT);
|
|
112
|
-
await new Promise(r => setTimeout(r, 50));
|
|
113
|
-
const dirA = '/projects/alpha';
|
|
114
|
-
const { messages, close } = await connectWs(PORT, dirA);
|
|
115
|
-
try {
|
|
116
|
-
dash.broadcast(makeEvent({ projectDir: dirA, nodeId: 'node-alpha' }));
|
|
117
|
-
await new Promise(r => setTimeout(r, 100));
|
|
118
|
-
const events = messages.filter((m) => m.eventType !== undefined);
|
|
119
|
-
expect(events.length).toBeGreaterThan(0);
|
|
120
|
-
expect(events[0].nodeId).toBe('node-alpha');
|
|
121
|
-
}
|
|
122
|
-
finally {
|
|
123
|
-
close();
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
it('?dir= filter — client with non-matching dir does NOT receive event', async () => {
|
|
127
|
-
const dash = startDashboard(PORT);
|
|
128
|
-
await new Promise(r => setTimeout(r, 50));
|
|
129
|
-
const { messages, close } = await connectWs(PORT, '/projects/beta');
|
|
130
|
-
try {
|
|
131
|
-
dash.broadcast(makeEvent({ projectDir: '/projects/alpha', nodeId: 'node-alpha-only' }));
|
|
132
|
-
await new Promise(r => setTimeout(r, 100));
|
|
133
|
-
const events = messages.filter((m) => m.eventType !== undefined);
|
|
134
|
-
expect(events.length).toBe(0);
|
|
135
|
-
}
|
|
136
|
-
finally {
|
|
137
|
-
close();
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
it('client without ?dir= receives all broadcasts', async () => {
|
|
141
|
-
const dash = startDashboard(PORT);
|
|
142
|
-
await new Promise(r => setTimeout(r, 50));
|
|
143
|
-
const { messages, close } = await connectWs(PORT);
|
|
144
|
-
try {
|
|
145
|
-
dash.broadcast(makeEvent({ projectDir: '/projects/alpha', nodeId: 'all-1' }));
|
|
146
|
-
dash.broadcast(makeEvent({ projectDir: '/projects/beta', nodeId: 'all-2' }));
|
|
147
|
-
await new Promise(r => setTimeout(r, 150));
|
|
148
|
-
const events = messages.filter((m) => m.eventType !== undefined);
|
|
149
|
-
expect(events.length).toBeGreaterThanOrEqual(2);
|
|
150
|
-
}
|
|
151
|
-
finally {
|
|
152
|
-
close();
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
describe('GET /events SSE endpoint', () => {
|
|
157
|
-
it('returns text/event-stream content-type when ws is unavailable', async () => {
|
|
158
|
-
// The dashboard is already started in ws mode on PORT.
|
|
159
|
-
// We verify the /events endpoint returns 404 in ws mode (ws is installed),
|
|
160
|
-
// which confirms the conditional branching works correctly.
|
|
161
|
-
const dash = startDashboard(PORT);
|
|
162
|
-
await new Promise(r => setTimeout(r, 50));
|
|
163
|
-
const res = await fetch(`http://127.0.0.1:${PORT}/events`, {
|
|
164
|
-
headers: { Accept: 'text/event-stream' },
|
|
165
|
-
});
|
|
166
|
-
// In ws mode the SSE endpoint is not registered — server returns 404
|
|
167
|
-
// In SSE-only mode it would return 200 with text/event-stream
|
|
168
|
-
// We test what the current mode actually does
|
|
169
|
-
if (res.status === 200) {
|
|
170
|
-
expect(res.headers.get('content-type')).toContain('text/event-stream');
|
|
171
|
-
await res.body?.cancel();
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
// ws mode: SSE not registered
|
|
175
|
-
expect(res.status).toBe(404);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
//# sourceMappingURL=browse-dashboard.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-dashboard.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-dashboard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-engine.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-engine.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { runPlaybook } from '@monoes/monobrowse';
|
|
3
|
-
const triggerNode = { id: 'trigger', type: 'trigger.manual', config: {} };
|
|
4
|
-
describe('runPlaybook', () => {
|
|
5
|
-
it('runs a single-node trigger workflow', async () => {
|
|
6
|
-
const def = {
|
|
7
|
-
id: 'wf-1', name: 'Test', nodes: [triggerNode], connections: [],
|
|
8
|
-
};
|
|
9
|
-
const record = await runPlaybook(def);
|
|
10
|
-
expect(record.status).toBe('completed');
|
|
11
|
-
expect(record.playbookId).toBe('wf-1');
|
|
12
|
-
});
|
|
13
|
-
it('rejects cyclic workflow', async () => {
|
|
14
|
-
const def = {
|
|
15
|
-
id: 'cyclic', name: 'Cyclic',
|
|
16
|
-
nodes: [
|
|
17
|
-
{ id: 'a', type: 'core.set', config: {} },
|
|
18
|
-
{ id: 'b', type: 'core.set', config: {} },
|
|
19
|
-
],
|
|
20
|
-
connections: [{ from: 'a', to: 'b' }, { from: 'b', to: 'a' }],
|
|
21
|
-
};
|
|
22
|
-
await expect(runPlaybook(def)).rejects.toThrow('cycle');
|
|
23
|
-
});
|
|
24
|
-
it('calls node handlers for action nodes', async () => {
|
|
25
|
-
const handler = vi.fn().mockResolvedValue([{ data: { result: 'ok' } }]);
|
|
26
|
-
const def = {
|
|
27
|
-
id: 'wf-2', name: 'Action Test',
|
|
28
|
-
nodes: [
|
|
29
|
-
triggerNode,
|
|
30
|
-
{ id: 'act', type: 'action.linkedin.comment_post', config: { text: 'hi' } },
|
|
31
|
-
],
|
|
32
|
-
connections: [{ from: 'trigger', to: 'act' }],
|
|
33
|
-
};
|
|
34
|
-
const handlers = new Map([['action.linkedin.comment_post', handler]]);
|
|
35
|
-
const record = await runPlaybook(def, { handlers });
|
|
36
|
-
expect(handler).toHaveBeenCalled();
|
|
37
|
-
expect(record.status).toBe('completed');
|
|
38
|
-
});
|
|
39
|
-
it('emits step events in order', async () => {
|
|
40
|
-
const events = [];
|
|
41
|
-
const def = { id: 'wf-3', name: 'Events', nodes: [triggerNode], connections: [] };
|
|
42
|
-
await runPlaybook(def, { onEvent: e => events.push(e.eventType) });
|
|
43
|
-
expect(events[0]).toBe('run_started');
|
|
44
|
-
expect(events[events.length - 1]).toBe('run_completed');
|
|
45
|
-
});
|
|
46
|
-
it('skips failed node when onError is skip', async () => {
|
|
47
|
-
const handler = vi.fn().mockRejectedValue(new Error('fail'));
|
|
48
|
-
const def = {
|
|
49
|
-
id: 'wf-4', name: 'Skip',
|
|
50
|
-
nodes: [
|
|
51
|
-
triggerNode,
|
|
52
|
-
{ id: 'bad', type: 'action.x.fail', config: {}, onError: 'skip' },
|
|
53
|
-
],
|
|
54
|
-
connections: [{ from: 'trigger', to: 'bad' }],
|
|
55
|
-
};
|
|
56
|
-
const handlers = new Map([['action.x.fail', handler]]);
|
|
57
|
-
const record = await runPlaybook(def, { handlers });
|
|
58
|
-
expect(record.status).toBe('completed');
|
|
59
|
-
});
|
|
60
|
-
it('stops on node failure when onError is stop (default)', async () => {
|
|
61
|
-
const handler = vi.fn().mockRejectedValue(new Error('boom'));
|
|
62
|
-
const def = {
|
|
63
|
-
id: 'wf-5', name: 'Stop',
|
|
64
|
-
nodes: [
|
|
65
|
-
triggerNode,
|
|
66
|
-
{ id: 'bad', type: 'action.x.fail', config: {} },
|
|
67
|
-
],
|
|
68
|
-
connections: [{ from: 'trigger', to: 'bad' }],
|
|
69
|
-
};
|
|
70
|
-
const handlers = new Map([['action.x.fail', handler]]);
|
|
71
|
-
const record = await runPlaybook(def, { handlers });
|
|
72
|
-
expect(record.status).toBe('failed');
|
|
73
|
-
expect(record.error).toContain('boom');
|
|
74
|
-
});
|
|
75
|
-
it('stops when AbortSignal is aborted', async () => {
|
|
76
|
-
const controller = new AbortController();
|
|
77
|
-
controller.abort();
|
|
78
|
-
const def = { id: 'wf-6', name: 'Abort', nodes: [triggerNode], connections: [] };
|
|
79
|
-
const record = await runPlaybook(def, { signal: controller.signal });
|
|
80
|
-
expect(record.status).toBe('stopped');
|
|
81
|
-
});
|
|
82
|
-
it('core.set transforms item fields', async () => {
|
|
83
|
-
const def = {
|
|
84
|
-
id: 'wf-7', name: 'Set',
|
|
85
|
-
nodes: [
|
|
86
|
-
{ id: 'trigger', type: 'trigger.manual', config: { items: [{ data: { x: 1 } }] } },
|
|
87
|
-
{ id: 'setNode', type: 'core.set', config: { y: 'hardcoded' } },
|
|
88
|
-
],
|
|
89
|
-
connections: [{ from: 'trigger', to: 'setNode' }],
|
|
90
|
-
};
|
|
91
|
-
const events = [];
|
|
92
|
-
const record = await runPlaybook(def, { onEvent: e => events.push(e) });
|
|
93
|
-
expect(record.status).toBe('completed');
|
|
94
|
-
});
|
|
95
|
-
it('throws for unregistered action handler', async () => {
|
|
96
|
-
const def = {
|
|
97
|
-
id: 'wf-8', name: 'NoHandler',
|
|
98
|
-
nodes: [
|
|
99
|
-
triggerNode,
|
|
100
|
-
{ id: 'act', type: 'action.missing.thing', config: {} },
|
|
101
|
-
],
|
|
102
|
-
connections: [{ from: 'trigger', to: 'act' }],
|
|
103
|
-
};
|
|
104
|
-
const record = await runPlaybook(def);
|
|
105
|
-
expect(record.status).toBe('failed');
|
|
106
|
-
expect(record.error).toContain('No handler registered');
|
|
107
|
-
});
|
|
108
|
-
it('core.filter keeps matching items', async () => {
|
|
109
|
-
const def = {
|
|
110
|
-
id: 'wf-filter', name: 'Filter',
|
|
111
|
-
nodes: [
|
|
112
|
-
{ id: 'trigger', type: 'trigger.manual', config: { items: [{ data: { x: 1 } }, { data: { x: 2 } }, { data: { x: 3 } }] } },
|
|
113
|
-
{ id: 'filter', type: 'core.filter', config: { expression: '{{$json.x}}' } },
|
|
114
|
-
],
|
|
115
|
-
connections: [{ from: 'trigger', to: 'filter' }],
|
|
116
|
-
};
|
|
117
|
-
const record = await runPlaybook(def);
|
|
118
|
-
expect(record.status).toBe('completed');
|
|
119
|
-
expect(record.itemsProcessed).toBeGreaterThan(0);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
//# sourceMappingURL=browse-engine.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-engine.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-engine.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-expression.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-expression.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
2
|
-
import { resolveExpression, resolveConfig } from '@monoes/monobrowse';
|
|
3
|
-
const item = { data: { url: 'https://linkedin.com/post/123', comment: 'Great post!' } };
|
|
4
|
-
const nodeOutputs = {
|
|
5
|
-
'trigger': [{ data: { url: 'https://linkedin.com/post/123' } }],
|
|
6
|
-
};
|
|
7
|
-
const params = { text: 'Hello world', post_url: 'https://linkedin.com/post/123' };
|
|
8
|
-
describe('resolveExpression', () => {
|
|
9
|
-
it('resolves $json fields', () => {
|
|
10
|
-
expect(resolveExpression('{{$json.url}}', item, nodeOutputs, params)).toBe('https://linkedin.com/post/123');
|
|
11
|
-
});
|
|
12
|
-
it('resolves $env variables', () => {
|
|
13
|
-
vi.stubEnv('TEST_VAR', 'test-value');
|
|
14
|
-
expect(resolveExpression('{{$env.TEST_VAR}}', item, nodeOutputs, params)).toBe('test-value');
|
|
15
|
-
});
|
|
16
|
-
it('resolves params', () => {
|
|
17
|
-
expect(resolveExpression('{{params.text}}', item, nodeOutputs, params)).toBe('Hello world');
|
|
18
|
-
});
|
|
19
|
-
it('resolves node output references', () => {
|
|
20
|
-
expect(resolveExpression('{{$node.trigger.url}}', item, nodeOutputs, params)).toBe('https://linkedin.com/post/123');
|
|
21
|
-
});
|
|
22
|
-
it('resolves $node bracket notation', () => {
|
|
23
|
-
expect(resolveExpression('{{$node["trigger"].url}}', item, nodeOutputs, params)).toBe('https://linkedin.com/post/123');
|
|
24
|
-
});
|
|
25
|
-
it('returns raw string if no template markers', () => {
|
|
26
|
-
expect(resolveExpression('plain text', item, nodeOutputs, params)).toBe('plain text');
|
|
27
|
-
});
|
|
28
|
-
it('throws on unresolved expression', () => {
|
|
29
|
-
expect(() => resolveExpression('{{$json.missing}}', item, nodeOutputs, params)).toThrow('Unresolved');
|
|
30
|
-
});
|
|
31
|
-
it('replaces duplicate placeholders in a single template', () => {
|
|
32
|
-
const doubled = { data: { x: 'hello' } };
|
|
33
|
-
expect(resolveExpression('{{$json.x}} and {{$json.x}}', doubled, {}, {})).toBe('hello and hello');
|
|
34
|
-
});
|
|
35
|
-
it('throws when $node output array is empty', () => {
|
|
36
|
-
expect(() => resolveExpression('{{$node.empty.field}}', item, { empty: [] }, params)).toThrow('Unresolved');
|
|
37
|
-
});
|
|
38
|
-
it('throws when $node bracket field is missing', () => {
|
|
39
|
-
expect(() => resolveExpression('{{$node["trigger"].missing}}', item, nodeOutputs, params)).toThrow('Unresolved');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
vi.unstubAllEnvs();
|
|
44
|
-
});
|
|
45
|
-
describe('resolveConfig', () => {
|
|
46
|
-
it('resolves all string values in a config object', () => {
|
|
47
|
-
const config = { post_url: '{{$json.url}}', text: '{{params.text}}', count: 3 };
|
|
48
|
-
const result = resolveConfig(config, item, nodeOutputs, params);
|
|
49
|
-
expect(result.post_url).toBe('https://linkedin.com/post/123');
|
|
50
|
-
expect(result.text).toBe('Hello world');
|
|
51
|
-
expect(result.count).toBe(3);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
//# sourceMappingURL=browse-expression.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-expression.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-expression.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-store.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { readPlaybook, writePlaybookRun, listPlaybookRuns, readAction, clearRunStore } from '@monoes/monobrowse';
|
|
3
|
-
import { writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { tmpdir } from 'node:os';
|
|
6
|
-
const TMP = join(tmpdir(), 'browse-store-test-' + Date.now());
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
clearRunStore();
|
|
9
|
-
mkdirSync(join(TMP, 'playbooks'), { recursive: true });
|
|
10
|
-
mkdirSync(join(TMP, 'actions'), { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
rmSync(TMP, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
describe('readPlaybook', () => {
|
|
16
|
-
it('parses a valid playbook JSON file', async () => {
|
|
17
|
-
const pb = {
|
|
18
|
-
id: 'test-pb',
|
|
19
|
-
name: 'Test Playbook',
|
|
20
|
-
nodes: [{ id: 'trigger', type: 'trigger.manual', config: {} }],
|
|
21
|
-
connections: [],
|
|
22
|
-
};
|
|
23
|
-
const p = join(TMP, 'playbooks', 'test.json');
|
|
24
|
-
writeFileSync(p, JSON.stringify(pb));
|
|
25
|
-
const result = await readPlaybook(p);
|
|
26
|
-
expect(result.id).toBe('test-pb');
|
|
27
|
-
expect(result.nodes).toHaveLength(1);
|
|
28
|
-
});
|
|
29
|
-
it('throws on missing file', async () => {
|
|
30
|
-
await expect(readPlaybook(join(TMP, 'nonexistent.json'))).rejects.toThrow();
|
|
31
|
-
});
|
|
32
|
-
it('throws on invalid JSON', async () => {
|
|
33
|
-
const p = join(TMP, 'playbooks', 'bad.json');
|
|
34
|
-
writeFileSync(p, 'not json');
|
|
35
|
-
await expect(readPlaybook(p)).rejects.toThrow();
|
|
36
|
-
});
|
|
37
|
-
it('throws if nodes array is missing', async () => {
|
|
38
|
-
const p = join(TMP, 'playbooks', 'no-nodes.json');
|
|
39
|
-
writeFileSync(p, JSON.stringify({ id: 'x', name: 'y', connections: [] }));
|
|
40
|
-
await expect(readPlaybook(p)).rejects.toThrow('nodes');
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
describe('readAction', () => {
|
|
44
|
-
it('parses a valid action JSON file', async () => {
|
|
45
|
-
const action = {
|
|
46
|
-
id: 'linkedin:comment_post',
|
|
47
|
-
platform: 'linkedin',
|
|
48
|
-
name: 'Comment on Post',
|
|
49
|
-
params: ['post_url', 'text'],
|
|
50
|
-
steps: [],
|
|
51
|
-
};
|
|
52
|
-
const p = join(TMP, 'actions', 'comment.json');
|
|
53
|
-
writeFileSync(p, JSON.stringify(action));
|
|
54
|
-
const result = await readAction(p);
|
|
55
|
-
expect(result.id).toBe('linkedin:comment_post');
|
|
56
|
-
expect(result.params).toContain('post_url');
|
|
57
|
-
});
|
|
58
|
-
it('throws on missing action file', async () => {
|
|
59
|
-
await expect(readAction(join(TMP, 'actions', 'nonexistent.json'))).rejects.toThrow();
|
|
60
|
-
});
|
|
61
|
-
it('throws on invalid action JSON', async () => {
|
|
62
|
-
const p = join(TMP, 'actions', 'bad.json');
|
|
63
|
-
writeFileSync(p, 'not json');
|
|
64
|
-
await expect(readAction(p)).rejects.toThrow();
|
|
65
|
-
});
|
|
66
|
-
it('throws if action steps array is missing', async () => {
|
|
67
|
-
const p = join(TMP, 'actions', 'no-steps.json');
|
|
68
|
-
writeFileSync(p, JSON.stringify({ id: 'x', platform: 'y', name: 'z', params: [] }));
|
|
69
|
-
await expect(readAction(p)).rejects.toThrow('steps');
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe('writePlaybookRun + listPlaybookRuns', () => {
|
|
73
|
-
it('stores and retrieves run records', async () => {
|
|
74
|
-
const record = {
|
|
75
|
-
id: 'run-1',
|
|
76
|
-
playbookId: 'pb-1',
|
|
77
|
-
playbookName: 'Test PB',
|
|
78
|
-
status: 'completed',
|
|
79
|
-
startedAt: Date.now(),
|
|
80
|
-
completedAt: Date.now() + 1000,
|
|
81
|
-
itemsProcessed: 5,
|
|
82
|
-
itemsTotal: 5,
|
|
83
|
-
};
|
|
84
|
-
await writePlaybookRun(record);
|
|
85
|
-
const runs = await listPlaybookRuns();
|
|
86
|
-
const found = runs.find(r => r.id === 'run-1');
|
|
87
|
-
expect(found).toBeDefined();
|
|
88
|
-
expect(found?.status).toBe('completed');
|
|
89
|
-
});
|
|
90
|
-
it('filters runs by playbookId', async () => {
|
|
91
|
-
const r1 = { id: 'r1', playbookId: 'pb-a', playbookName: 'A', status: 'completed', startedAt: 1, itemsProcessed: 1, itemsTotal: 1 };
|
|
92
|
-
const r2 = { id: 'r2', playbookId: 'pb-b', playbookName: 'B', status: 'failed', startedAt: 2, itemsProcessed: 0, itemsTotal: 1 };
|
|
93
|
-
await writePlaybookRun(r1);
|
|
94
|
-
await writePlaybookRun(r2);
|
|
95
|
-
const runs = await listPlaybookRuns('pb-a');
|
|
96
|
-
expect(runs.every(r => r.playbookId === 'pb-a')).toBe(true);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
//# sourceMappingURL=browse-store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-store.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-workflow-types.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browse-workflow-types.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
describe('PlaybookDef', () => {
|
|
3
|
-
it('accepts a valid playbook definition', () => {
|
|
4
|
-
const wf = {
|
|
5
|
-
id: 'my-playbook',
|
|
6
|
-
name: 'My Playbook',
|
|
7
|
-
nodes: [
|
|
8
|
-
{ id: 'n1', type: 'trigger.manual', config: {} },
|
|
9
|
-
{ id: 'n2', type: 'action.linkedin.comment_post', config: { post_url: '{{$json.url}}', text: 'hi' } },
|
|
10
|
-
],
|
|
11
|
-
connections: [{ from: 'n1', to: 'n2' }],
|
|
12
|
-
};
|
|
13
|
-
expect(wf.nodes).toHaveLength(2);
|
|
14
|
-
expect(wf.connections[0].from).toBe('n1');
|
|
15
|
-
});
|
|
16
|
-
it('accepts a valid ActionDef with steps', () => {
|
|
17
|
-
const action = {
|
|
18
|
-
id: 'linkedin:comment_post',
|
|
19
|
-
platform: 'linkedin',
|
|
20
|
-
name: 'Comment on Post',
|
|
21
|
-
params: ['post_url', 'text'],
|
|
22
|
-
steps: [
|
|
23
|
-
{ type: 'navigate', url: '{{params.post_url}}' },
|
|
24
|
-
{ type: 'find', selectors: ['.comment-box', '[aria-label="Add a comment"]'], as: 'box' },
|
|
25
|
-
{ type: 'click', target: '{{box}}' },
|
|
26
|
-
{ type: 'type', target: '{{box}}', text: '{{params.text}}', humanDelay: true },
|
|
27
|
-
{ type: 'wait', condition: 'network_idle', timeout: 3000 },
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
expect(action.steps).toHaveLength(5);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
//# sourceMappingURL=browse-workflow-types.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browse-workflow-types.test.js","sourceRoot":"","sources":["../../../src/__tests__/browse-workflow-types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI9C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,EAAE,GAAgB;YACtB,EAAE,EAAE,aAAa;YACjB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE;gBACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;gBAChD,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,8BAA8B,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;aACtG;YACD,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;SACxC,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAc;YACxB,EAAE,EAAE,uBAAuB;YAC3B,QAAQ,EAAE,UAAU;YACpB,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,KAAK,EAAE;gBACL,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,qBAAqB,EAAE;gBAChD,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,cAAc,EAAE,8BAA8B,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE;gBACxF,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;gBACpC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE;gBAC9E,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE;aAC3D;SACF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|