@commandgarden/cli 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/main.js +58 -28
  2. package/node_modules/@commandgarden/app/dist/client/index.html +17 -17
  3. package/node_modules/@commandgarden/app/dist/server/main.js +1 -1
  4. package/node_modules/@commandgarden/app/dist/server/routes/audit.js +27 -16
  5. package/node_modules/@commandgarden/app/dist/server/routes/config.js +8 -2
  6. package/node_modules/@commandgarden/app/dist/server/routes/connectors.js +37 -26
  7. package/node_modules/@commandgarden/app/dist/server/routes/run.js +3 -4
  8. package/node_modules/@commandgarden/app/dist/server/routes/status.js +2 -1
  9. package/node_modules/@commandgarden/app/dist/server/routes/utils.d.ts +2 -0
  10. package/node_modules/@commandgarden/app/dist/server/routes/utils.js +4 -0
  11. package/node_modules/@commandgarden/app/dist/server/store.js +53 -53
  12. package/node_modules/@commandgarden/app/package.json +42 -42
  13. package/node_modules/@commandgarden/chrome/dist/content-script.js.map +1 -1
  14. package/node_modules/@commandgarden/chrome/dist/manifest.json +26 -26
  15. package/node_modules/@commandgarden/chrome/dist/popup.html +218 -218
  16. package/node_modules/@commandgarden/chrome/dist/popup.js.map +1 -1
  17. package/node_modules/@commandgarden/chrome/dist/service-worker.js.map +1 -1
  18. package/node_modules/@commandgarden/chrome/package.json +26 -26
  19. package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.eval.js +100 -100
  20. package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.yaml +71 -71
  21. package/node_modules/@commandgarden/daemon/connectors/gcs-kb-content.yaml +61 -61
  22. package/node_modules/@commandgarden/daemon/connectors/gcs-kb-pages.yaml +54 -54
  23. package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.eval.js +115 -115
  24. package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.yaml +54 -54
  25. package/node_modules/@commandgarden/daemon/connectors/lib/msal-token.js +20 -20
  26. package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.eval.js +204 -204
  27. package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.yaml +42 -42
  28. package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.eval.js +94 -94
  29. package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.yaml +34 -34
  30. package/node_modules/@commandgarden/daemon/connectors/socket-security-news.yaml +63 -63
  31. package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.eval.js +437 -437
  32. package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.yaml +53 -53
  33. package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.eval.js +547 -547
  34. package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.yaml +48 -48
  35. package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.eval.js +52 -52
  36. package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.yaml +42 -42
  37. package/node_modules/@commandgarden/daemon/connectors/timetracking-report.eval.js +81 -81
  38. package/node_modules/@commandgarden/daemon/connectors/timetracking-report.yaml +52 -52
  39. package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.eval.js +27 -27
  40. package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.yaml +38 -38
  41. package/node_modules/@commandgarden/daemon/connectors/tokenmaster-clients-list.yaml +55 -55
  42. package/node_modules/@commandgarden/daemon/dist/audit-store.js +8 -8
  43. package/node_modules/@commandgarden/daemon/dist/auth.d.ts +1 -0
  44. package/node_modules/@commandgarden/daemon/dist/auth.d.ts.map +1 -1
  45. package/node_modules/@commandgarden/daemon/dist/auth.js +10 -0
  46. package/node_modules/@commandgarden/daemon/dist/auth.js.map +1 -1
  47. package/node_modules/@commandgarden/daemon/dist/main.js +12 -5
  48. package/node_modules/@commandgarden/daemon/dist/main.js.map +1 -1
  49. package/node_modules/@commandgarden/daemon/dist/server.d.ts.map +1 -1
  50. package/node_modules/@commandgarden/daemon/dist/server.js +10 -0
  51. package/node_modules/@commandgarden/daemon/dist/server.js.map +1 -1
  52. package/node_modules/@commandgarden/daemon/package.json +32 -32
  53. package/node_modules/@commandgarden/shared/dist/daemon-client.d.ts +5 -1
  54. package/node_modules/@commandgarden/shared/dist/daemon-client.d.ts.map +1 -1
  55. package/node_modules/@commandgarden/shared/dist/daemon-client.js +32 -14
  56. package/node_modules/@commandgarden/shared/dist/daemon-client.js.map +1 -1
  57. package/node_modules/@commandgarden/shared/package.json +32 -32
  58. package/package.json +58 -58
  59. package/node_modules/@commandgarden/app/dist/server/daemon-client.test.js +0 -47
  60. package/node_modules/@commandgarden/app/dist/server/routes/routes.test.js +0 -137
  61. package/node_modules/@commandgarden/app/dist/server/store.test.js +0 -59
  62. package/node_modules/@commandgarden/chrome/dist/fetch-interceptor.js +0 -44
  63. package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts +0 -24
  64. package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts.map +0 -1
  65. package/node_modules/@commandgarden/daemon/dist/cdp-client.js +0 -150
  66. package/node_modules/@commandgarden/daemon/dist/cdp-client.js.map +0 -1
@@ -1,32 +1,32 @@
1
- {
2
- "name": "@commandgarden/shared",
3
- "version": "0.1.0",
4
- "description": "Shared types and utilities for CommandGarden",
5
- "private": true,
6
- "type": "module",
7
- "main": "./dist/index.js",
8
- "files": [
9
- "dist"
10
- ],
11
- "types": "./dist/index.d.ts",
12
- "exports": {
13
- ".": {
14
- "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js"
16
- }
17
- },
18
- "scripts": {
19
- "build": "tsc",
20
- "test": "vitest run",
21
- "test:watch": "vitest"
22
- },
23
- "dependencies": {
24
- "yaml": "^2.4.0",
25
- "zod": "^3.23.0"
26
- },
27
- "devDependencies": {
28
- "@types/node": "^26.0.0",
29
- "typescript": "^5.4.0",
30
- "vitest": "^2.0.0"
31
- }
32
- }
1
+ {
2
+ "name": "@commandgarden/shared",
3
+ "version": "0.1.0",
4
+ "description": "Shared types and utilities for CommandGarden",
5
+ "private": true,
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest"
22
+ },
23
+ "dependencies": {
24
+ "yaml": "^2.4.0",
25
+ "zod": "^3.23.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^26.0.0",
29
+ "typescript": "^5.4.0",
30
+ "vitest": "^2.0.0"
31
+ }
32
+ }
package/package.json CHANGED
@@ -1,58 +1,58 @@
1
- {
2
- "name": "@commandgarden/cli",
3
- "version": "2.13.0",
4
- "description": "Enterprise browser automation CLI",
5
- "type": "module",
6
- "license": "MIT",
7
- "main": "./dist/main.js",
8
- "bin": {
9
- "commandgarden": "dist/main.js",
10
- "cg": "dist/main.js"
11
- },
12
- "files": [
13
- "dist"
14
- ],
15
- "engines": {
16
- "node": ">=20"
17
- },
18
- "keywords": [
19
- "browser-automation",
20
- "cli",
21
- "enterprise",
22
- "commandgarden"
23
- ],
24
- "scripts": {
25
- "build": "tsup",
26
- "prepack": "node scripts/prepare-bundle.mjs",
27
- "start": "node dist/main.js",
28
- "test": "vitest run",
29
- "test:watch": "vitest"
30
- },
31
- "bundleDependencies": [
32
- "@commandgarden/chrome",
33
- "@commandgarden/daemon",
34
- "@commandgarden/app",
35
- "@commandgarden/shared"
36
- ],
37
- "dependencies": {
38
- "@commandgarden/app": "*",
39
- "@commandgarden/chrome": "*",
40
- "@commandgarden/daemon": "*",
41
- "@commandgarden/shared": "*",
42
- "@fastify/static": "^8.0.0",
43
- "@fastify/websocket": "^11.0.0",
44
- "sql.js": "^1.11.0",
45
- "turndown": "^7.2.4",
46
- "cli-table3": "^0.6.0",
47
- "commander": "^12.0.0",
48
- "fastify": "^5.0.0",
49
- "yaml": "^2.4.0",
50
- "zod": "^3.23.0"
51
- },
52
- "devDependencies": {
53
- "@types/node": "^22.0.0",
54
- "tsup": "^8.5.1",
55
- "typescript": "^5.4.0",
56
- "vitest": "^2.0.0"
57
- }
58
- }
1
+ {
2
+ "name": "@commandgarden/cli",
3
+ "version": "2.14.0",
4
+ "description": "Enterprise browser automation CLI",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "main": "./dist/main.js",
8
+ "bin": {
9
+ "commandgarden": "dist/main.js",
10
+ "cg": "dist/main.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "keywords": [
19
+ "browser-automation",
20
+ "cli",
21
+ "enterprise",
22
+ "commandgarden"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "prepack": "node scripts/prepare-bundle.mjs",
27
+ "start": "node dist/main.js",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest"
30
+ },
31
+ "bundleDependencies": [
32
+ "@commandgarden/chrome",
33
+ "@commandgarden/daemon",
34
+ "@commandgarden/app",
35
+ "@commandgarden/shared"
36
+ ],
37
+ "dependencies": {
38
+ "@commandgarden/app": "*",
39
+ "@commandgarden/chrome": "*",
40
+ "@commandgarden/daemon": "*",
41
+ "@commandgarden/shared": "*",
42
+ "@fastify/static": "^8.0.0",
43
+ "@fastify/websocket": "^11.0.0",
44
+ "sql.js": "^1.11.0",
45
+ "turndown": "^7.2.4",
46
+ "cli-table3": "^0.6.0",
47
+ "commander": "^12.0.0",
48
+ "fastify": "^5.0.0",
49
+ "yaml": "^2.4.0",
50
+ "zod": "^3.23.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.0.0",
54
+ "tsup": "^8.5.1",
55
+ "typescript": "^5.4.0",
56
+ "vitest": "^2.0.0"
57
+ }
58
+ }
@@ -1,47 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { DaemonClient } from './daemon-client.js';
3
- describe('DaemonClient', () => {
4
- let client;
5
- const mockFetch = vi.fn();
6
- beforeEach(() => {
7
- vi.stubGlobal('fetch', mockFetch);
8
- client = new DaemonClient('http://127.0.0.1:19825', 'test-token');
9
- mockFetch.mockReset();
10
- });
11
- it('sends auth headers on GET', async () => {
12
- mockFetch.mockResolvedValueOnce({
13
- ok: true,
14
- json: () => Promise.resolve({ ok: true, data: 'test' }),
15
- });
16
- await client.get('/api/status');
17
- expect(mockFetch).toHaveBeenCalledWith('http://127.0.0.1:19825/api/status', expect.objectContaining({
18
- method: 'GET',
19
- headers: expect.objectContaining({
20
- Authorization: 'Bearer test-token',
21
- 'X-CommandGarden': '1',
22
- }),
23
- }));
24
- });
25
- it('sends body on POST', async () => {
26
- mockFetch.mockResolvedValueOnce({
27
- ok: true,
28
- json: () => Promise.resolve({ ok: true }),
29
- });
30
- await client.post('/api/run', { connector: 'test/cmd', args: {} });
31
- const call = mockFetch.mock.calls[0];
32
- expect(call[1].method).toBe('POST');
33
- expect(JSON.parse(call[1].body)).toEqual({ connector: 'test/cmd', args: {} });
34
- });
35
- it('throws on non-ok response', async () => {
36
- mockFetch.mockResolvedValueOnce({
37
- ok: false,
38
- status: 401,
39
- json: () => Promise.resolve({ error: 'Unauthorized' }),
40
- });
41
- await expect(client.get('/api/status')).rejects.toThrow('Unauthorized');
42
- });
43
- it('throws on network error', async () => {
44
- mockFetch.mockRejectedValueOnce(new Error('fetch failed'));
45
- await expect(client.get('/api/status')).rejects.toThrow('Cannot connect to daemon');
46
- });
47
- });
@@ -1,137 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import Fastify from 'fastify';
3
- import { registerRoutes } from './index.js';
4
- import { AppStore } from '../store.js';
5
- function mockDaemon() {
6
- return {
7
- get: vi.fn(),
8
- post: vi.fn(),
9
- pipeRaw: vi.fn(),
10
- };
11
- }
12
- describe('routes', () => {
13
- let app;
14
- let daemon;
15
- let store;
16
- beforeEach(async () => {
17
- app = Fastify();
18
- daemon = mockDaemon();
19
- store = new AppStore(':memory:');
20
- registerRoutes(app, daemon, store);
21
- await app.ready();
22
- });
23
- describe('GET /api/status', () => {
24
- it('proxies daemon status', async () => {
25
- daemon.get.mockResolvedValueOnce({
26
- ok: true, extensionConnected: true, connectorCount: 2,
27
- });
28
- const resp = await app.inject({ method: 'GET', url: '/api/status' });
29
- expect(resp.statusCode).toBe(200);
30
- const body = JSON.parse(resp.payload);
31
- expect(body.ok).toBe(true);
32
- expect(body.extensionConnected).toBe(true);
33
- });
34
- });
35
- describe('GET /api/connectors', () => {
36
- it('proxies and enriches connector list', async () => {
37
- daemon.get
38
- .mockImplementation((path) => {
39
- if (path === '/api/connectors') {
40
- return Promise.resolve({
41
- ok: true,
42
- connectors: [
43
- { key: 'timetracking/report', description: 'test', access: 'read', domains: [], capabilities: [] },
44
- ],
45
- });
46
- }
47
- if (path === '/api/config') {
48
- return Promise.resolve({
49
- ok: true,
50
- config: { security: { highRiskCapabilities: ['js_evaluate', 'cookie_write'], approvedHighRisk: [], autoApproveConnectors: [] } },
51
- });
52
- }
53
- return Promise.resolve({ ok: true });
54
- });
55
- const resp = await app.inject({ method: 'GET', url: '/api/connectors' });
56
- expect(resp.statusCode).toBe(200);
57
- const body = JSON.parse(resp.payload);
58
- expect(body.connectors).toHaveLength(1);
59
- expect(body.connectors[0].hasAppPage).toBe(true);
60
- expect(body.connectors[0].appRoute).toBe('/apps/timetracking');
61
- });
62
- it('enriches connectors with security flags from config', async () => {
63
- daemon.get
64
- .mockImplementation((path) => {
65
- if (path === '/api/connectors') {
66
- return Promise.resolve({
67
- ok: true,
68
- connectors: [
69
- { key: 'timetracking/report', description: 'test', access: 'read', domains: [], capabilities: ['navigate', 'js_evaluate'] },
70
- { key: 'safe/connector', description: 'safe', access: 'read', domains: [], capabilities: ['navigate'] },
71
- ],
72
- });
73
- }
74
- if (path === '/api/config') {
75
- return Promise.resolve({
76
- ok: true,
77
- config: {
78
- security: {
79
- highRiskCapabilities: ['js_evaluate', 'cookie_write'],
80
- approvedHighRisk: ['timetracking/report'],
81
- autoApproveConnectors: ['timetracking/report'],
82
- },
83
- },
84
- });
85
- }
86
- return Promise.resolve({ ok: true });
87
- });
88
- const resp = await app.inject({ method: 'GET', url: '/api/connectors' });
89
- const body = JSON.parse(resp.payload);
90
- expect(body.connectors[0].isHighRisk).toBe(true);
91
- expect(body.connectors[0].isApproved).toBe(true);
92
- expect(body.connectors[0].isAutoApproved).toBe(true);
93
- expect(body.connectors[1].isHighRisk).toBe(false);
94
- expect(body.connectors[1].isApproved).toBe(false);
95
- expect(body.connectors[1].isAutoApproved).toBe(false);
96
- });
97
- });
98
- describe('GET /api/preferences', () => {
99
- it('returns empty preferences', async () => {
100
- const resp = await app.inject({ method: 'GET', url: '/api/preferences' });
101
- expect(resp.statusCode).toBe(200);
102
- expect(JSON.parse(resp.payload)).toEqual({ ok: true, preferences: {} });
103
- });
104
- it('sets and gets a preference via PUT', async () => {
105
- await app.inject({
106
- method: 'PUT', url: '/api/preferences',
107
- payload: { key: 'theme', value: 'dark' },
108
- });
109
- const resp = await app.inject({ method: 'GET', url: '/api/preferences' });
110
- expect(JSON.parse(resp.payload).preferences).toEqual({ theme: 'dark' });
111
- });
112
- });
113
- describe('POST /api/run', () => {
114
- it('proxies run to daemon', async () => {
115
- daemon.post.mockResolvedValueOnce({
116
- ok: true, data: [{ a: 1 }], rowCount: 1,
117
- });
118
- const resp = await app.inject({
119
- method: 'POST', url: '/api/run',
120
- payload: { connector: 'test/cmd', args: {} },
121
- });
122
- expect(resp.statusCode).toBe(200);
123
- expect(JSON.parse(resp.payload).ok).toBe(true);
124
- });
125
- it('returns 502 with error message when daemon throws', async () => {
126
- daemon.post.mockRejectedValueOnce(new Error('Extension not connected'));
127
- const resp = await app.inject({
128
- method: 'POST', url: '/api/run',
129
- payload: { connector: 'test/cmd', args: {} },
130
- });
131
- expect(resp.statusCode).toBe(502);
132
- const body = JSON.parse(resp.payload);
133
- expect(body.ok).toBe(false);
134
- expect(body.error).toBe('Extension not connected');
135
- });
136
- });
137
- });
@@ -1,59 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { AppStore } from './store.js';
3
- describe('AppStore', () => {
4
- let store;
5
- beforeEach(() => {
6
- store = new AppStore(':memory:');
7
- });
8
- afterEach(() => {
9
- store.close();
10
- });
11
- describe('preferences', () => {
12
- it('returns undefined for missing key', () => {
13
- expect(store.getPreference('missing')).toBeUndefined();
14
- });
15
- it('sets and gets a preference', () => {
16
- store.setPreference('theme', 'light');
17
- expect(store.getPreference('theme')).toBe('light');
18
- });
19
- it('overwrites existing preference', () => {
20
- store.setPreference('theme', 'light');
21
- store.setPreference('theme', 'dark');
22
- expect(store.getPreference('theme')).toBe('dark');
23
- });
24
- it('returns all preferences', () => {
25
- store.setPreference('a', '1');
26
- store.setPreference('b', '2');
27
- expect(store.getAllPreferences()).toEqual({ a: '1', b: '2' });
28
- });
29
- });
30
- describe('saved views', () => {
31
- it('returns empty array when no views', () => {
32
- expect(store.listViews('timetracking')).toEqual([]);
33
- });
34
- it('creates and lists a view', () => {
35
- const view = store.createView('timetracking', 'June report', '{"month":"2026-06"}');
36
- expect(view.id).toBeDefined();
37
- expect(view.app).toBe('timetracking');
38
- expect(view.name).toBe('June report');
39
- expect(view.config).toBe('{"month":"2026-06"}');
40
- const views = store.listViews('timetracking');
41
- expect(views).toHaveLength(1);
42
- expect(views[0].name).toBe('June report');
43
- });
44
- it('filters views by app', () => {
45
- store.createView('timetracking', 'View A', '{}');
46
- store.createView('rooms', 'View B', '{}');
47
- expect(store.listViews('timetracking')).toHaveLength(1);
48
- expect(store.listViews('rooms')).toHaveLength(1);
49
- });
50
- it('deletes a view', () => {
51
- const view = store.createView('timetracking', 'To delete', '{}');
52
- expect(store.deleteView(view.id)).toBe(true);
53
- expect(store.listViews('timetracking')).toHaveLength(0);
54
- });
55
- it('returns false when deleting non-existent view', () => {
56
- expect(store.deleteView('nonexistent')).toBe(false);
57
- });
58
- });
59
- });
@@ -1,44 +0,0 @@
1
- // fetch-interceptor.js — injected at document_start in MAIN world.
2
- // Patches window.fetch BEFORE OWA's modules capture a reference to it.
3
- // Minimal — only the fetch patch, nothing else.
4
- (function () {
5
- if (window.__rfb) return;
6
- window.__rfb = [];
7
- window.__rfb_urls = [];
8
-
9
- // Intercept Service Worker messages — OWA sends getSchedule data
10
- // from the SW to the page via postMessage, bypassing window.fetch.
11
- if (navigator.serviceWorker) {
12
- navigator.serviceWorker.addEventListener('message', function (e) {
13
- try {
14
- var str = typeof e.data === 'string' ? e.data : JSON.stringify(e.data);
15
- if (str.indexOf('getSchedule') > -1 && str.indexOf('availabilityView') > -1) {
16
- window.__rfb.push({ req: '', body: str });
17
- }
18
- } catch (_e) { /* ignore */ }
19
- });
20
- }
21
-
22
- var origFetch = window.fetch;
23
- window.fetch = function () {
24
- var a = arguments;
25
- var u = (a[0] && a[0].url) || a[0] || '';
26
- var rb = (a[1] && a[1].body) || '';
27
- var uStr = String(u);
28
- if (window.__rfb_urls.length < 100) {
29
- window.__rfb_urls.push(uStr.slice(0, 120));
30
- }
31
- return origFetch.apply(this, a).then(function (r) {
32
- try {
33
- if (uStr.indexOf('graphql') > -1) {
34
- r.clone().text().then(function (t) {
35
- if (t.indexOf('getSchedule') > -1 && t.indexOf('availabilityView') > -1) {
36
- window.__rfb.push({ req: String(rb || ''), body: t });
37
- }
38
- }).catch(function () {});
39
- }
40
- } catch (_e) { /* ignore */ }
41
- return r;
42
- });
43
- };
44
- })();
@@ -1,24 +0,0 @@
1
- export declare class CdpClient {
2
- private port;
3
- private ws;
4
- private msgId;
5
- private pending;
6
- private sessionIds;
7
- constructor(port: number);
8
- /** Connect to Chrome's browser-level CDP endpoint. */
9
- connect(): Promise<void>;
10
- /** Send a CDP command to the browser target. */
11
- private send;
12
- /** Send a CDP command to a specific session (tab). */
13
- private sendToSession;
14
- /**
15
- * Enable Network domain on all matching tabs and future tabs.
16
- * Uses Target.setAutoAttach to automatically attach to new targets
17
- * (tabs created by the extension) and enable Network on them.
18
- */
19
- enableNetworkCapture(urlPattern?: string): Promise<void>;
20
- /** Disconnect from CDP. */
21
- disconnect(): void;
22
- get connected(): boolean;
23
- }
24
- //# sourceMappingURL=cdp-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cdp-client.d.ts","sourceRoot":"","sources":["../src/cdp-client.ts"],"names":[],"mappings":"AA6BA,qBAAa,SAAS;IAMR,OAAO,CAAC,IAAI;IALxB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAoF;IACnG,OAAO,CAAC,UAAU,CAAqB;gBAEnB,IAAI,EAAE,MAAM;IAEhC,sDAAsD;IAChD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD9B,gDAAgD;IAChD,OAAO,CAAC,IAAI;IAgBZ,sDAAsD;IACtD,OAAO,CAAC,aAAa;IAgBrB;;;;OAIG;IACG,oBAAoB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9D,2BAA2B;IAC3B,UAAU,IAAI,IAAI;IAYlB,IAAI,SAAS,IAAI,OAAO,CAA6B;CACtD"}
@@ -1,150 +0,0 @@
1
- // src/cdp-client.ts
2
- //
3
- // Lightweight CDP (Chrome DevTools Protocol) client that connects to Chrome's
4
- // --remote-debugging-port and calls Network.enable on target tabs. This forces
5
- // Chrome to route Service Worker-handled requests through the observable path,
6
- // making them visible to window.fetch interceptors in the page context.
7
- //
8
- // Without Network.enable, OWA's getSchedule GraphQL call goes through the
9
- // Service Worker's internal fetch — invisible to any page-level interception.
10
- import { WebSocket } from 'ws';
11
- export class CdpClient {
12
- port;
13
- ws = null;
14
- msgId = 0;
15
- pending = new Map();
16
- sessionIds = new Set();
17
- constructor(port) {
18
- this.port = port;
19
- }
20
- /** Connect to Chrome's browser-level CDP endpoint. */
21
- async connect() {
22
- const versionUrl = `http://127.0.0.1:${this.port}/json/version`;
23
- const resp = await fetch(versionUrl);
24
- if (!resp.ok)
25
- throw new Error(`CDP version endpoint returned ${resp.status}`);
26
- const info = await resp.json();
27
- const wsUrl = info.webSocketDebuggerUrl;
28
- if (!wsUrl)
29
- throw new Error('No webSocketDebuggerUrl in CDP version response');
30
- return new Promise((resolve, reject) => {
31
- const ws = new WebSocket(wsUrl);
32
- const timeout = setTimeout(() => {
33
- ws.close();
34
- reject(new Error('CDP WebSocket connection timed out'));
35
- }, 5000);
36
- ws.on('open', () => {
37
- clearTimeout(timeout);
38
- this.ws = ws;
39
- resolve();
40
- });
41
- ws.on('error', (err) => {
42
- clearTimeout(timeout);
43
- reject(new Error(`CDP WebSocket error: ${err.message}`));
44
- });
45
- ws.on('message', (data) => {
46
- try {
47
- const msg = JSON.parse(String(data));
48
- // Handle responses to our commands
49
- if (msg.id !== undefined) {
50
- const entry = this.pending.get(msg.id);
51
- if (entry) {
52
- this.pending.delete(msg.id);
53
- if (msg.error)
54
- entry.reject(new Error(msg.error.message));
55
- else
56
- entry.resolve(msg.result);
57
- }
58
- }
59
- // Handle Target.attachedToTarget — auto-enable Network on new sessions
60
- if (msg.method === 'Target.attachedToTarget' && msg.params) {
61
- const sessionId = msg.params.sessionId;
62
- if (sessionId) {
63
- this.sessionIds.add(sessionId);
64
- this.sendToSession(sessionId, 'Network.enable', {}).catch(() => { });
65
- }
66
- }
67
- }
68
- catch { /* ignore parse errors */ }
69
- });
70
- ws.on('close', () => { this.ws = null; });
71
- });
72
- }
73
- /** Send a CDP command to the browser target. */
74
- send(method, params = {}) {
75
- if (!this.ws)
76
- return Promise.reject(new Error('CDP not connected'));
77
- const id = ++this.msgId;
78
- return new Promise((resolve, reject) => {
79
- const timer = setTimeout(() => {
80
- this.pending.delete(id);
81
- reject(new Error(`CDP command ${method} timed out`));
82
- }, 10000);
83
- this.pending.set(id, {
84
- resolve: (r) => { clearTimeout(timer); resolve(r); },
85
- reject: (e) => { clearTimeout(timer); reject(e); },
86
- });
87
- this.ws.send(JSON.stringify({ id, method, params }));
88
- });
89
- }
90
- /** Send a CDP command to a specific session (tab). */
91
- sendToSession(sessionId, method, params = {}) {
92
- if (!this.ws)
93
- return Promise.reject(new Error('CDP not connected'));
94
- const id = ++this.msgId;
95
- return new Promise((resolve, reject) => {
96
- const timer = setTimeout(() => {
97
- this.pending.delete(id);
98
- reject(new Error(`CDP command ${method} timed out`));
99
- }, 10000);
100
- this.pending.set(id, {
101
- resolve: (r) => { clearTimeout(timer); resolve(r); },
102
- reject: (e) => { clearTimeout(timer); reject(e); },
103
- });
104
- this.ws.send(JSON.stringify({ id, method, params, sessionId }));
105
- });
106
- }
107
- /**
108
- * Enable Network domain on all matching tabs and future tabs.
109
- * Uses Target.setAutoAttach to automatically attach to new targets
110
- * (tabs created by the extension) and enable Network on them.
111
- */
112
- async enableNetworkCapture(urlPattern) {
113
- // Auto-attach to existing and new targets
114
- await this.send('Target.setAutoAttach', {
115
- autoAttach: true,
116
- waitForDebuggerOnStart: false,
117
- flatten: true,
118
- filter: [{ type: 'page' }],
119
- });
120
- // Also manually attach to existing tabs matching the URL pattern
121
- if (urlPattern) {
122
- const resp = await fetch(`http://127.0.0.1:${this.port}/json`);
123
- if (resp.ok) {
124
- const targets = await resp.json();
125
- for (const t of targets) {
126
- if (t.type === 'page' && t.url.includes(urlPattern)) {
127
- try {
128
- await this.send('Target.attachToTarget', { targetId: t.id, flatten: true });
129
- }
130
- catch { /* may already be attached */ }
131
- }
132
- }
133
- }
134
- }
135
- }
136
- /** Disconnect from CDP. */
137
- disconnect() {
138
- this.sessionIds.clear();
139
- for (const [, entry] of this.pending) {
140
- entry.reject(new Error('CDP disconnected'));
141
- }
142
- this.pending.clear();
143
- if (this.ws) {
144
- this.ws.close();
145
- this.ws = null;
146
- }
147
- }
148
- get connected() { return this.ws !== null; }
149
- }
150
- //# sourceMappingURL=cdp-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cdp-client.js","sourceRoot":"","sources":["../src/cdp-client.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,+EAA+E;AAC/E,wEAAwE;AACxE,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAE9E,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAmB/B,MAAM,OAAO,SAAS;IAMA;IALZ,EAAE,GAAqB,IAAI,CAAC;IAC5B,KAAK,GAAG,CAAC,CAAC;IACV,OAAO,GAAG,IAAI,GAAG,EAAyE,CAAC;IAC3F,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,YAAoB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAEpC,sDAAsD;IACtD,KAAK,CAAC,OAAO;QACX,MAAM,UAAU,GAAG,oBAAoB,IAAI,CAAC,IAAI,eAAe,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAsC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAE/E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC1D,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;gBACjB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAe,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;oBACjD,mCAAmC;oBACnC,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;wBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACvC,IAAI,KAAK,EAAE,CAAC;4BACV,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;4BAC5B,IAAI,GAAG,CAAC,KAAK;gCAAE,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;;gCACrD,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBACjC,CAAC;oBACH,CAAC;oBACD,uEAAuE;oBACvE,IAAI,GAAG,CAAC,MAAM,KAAK,yBAAyB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;wBAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAmB,CAAC;wBACjD,IAAI,SAAS,EAAE,CAAC;4BACd,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;4BAC/B,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;wBACtE,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gDAAgD;IACxC,IAAI,CAAC,MAAc,EAAE,SAAkC,EAAE;QAC/D,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACpE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;QACxB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,MAAM,YAAY,CAAC,CAAC,CAAC;YACvD,CAAC,EAAE,KAAK,CAAC,CAAC;YACV,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE;gBACnB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACnD,CAAC,CAAC;YACH,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sDAAsD;IAC9C,aAAa,CAAC,SAAiB,EAAE,MAAc,EAAE,SAAkC,EAAE;QAC3F,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACpE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;QACxB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,MAAM,YAAY,CAAC,CAAC,CAAC;YACvD,CAAC,EAAE,KAAK,CAAC,CAAC;YACV,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE;gBACnB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACnD,CAAC,CAAC;YACH,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,oBAAoB,CAAC,UAAmB;QAC5C,0CAA0C;QAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;YACtC,UAAU,EAAE,IAAI;YAChB,sBAAsB,EAAE,KAAK;YAC7B,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SAC3B,CAAC,CAAC;QAEH,iEAAiE;QACjE,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC;YAC/D,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAiB,CAAC;gBACjD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACxB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;wBACpD,IAAI,CAAC;4BACH,MAAM,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC9E,CAAC;wBAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;oBAC3C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,UAAU;QACR,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,KAAc,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;CACtD"}