webclaw-shared 0.1.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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/dist/__tests__/message.test.d.ts +2 -0
  3. package/dist/__tests__/message.test.d.ts.map +1 -0
  4. package/dist/__tests__/message.test.js +83 -0
  5. package/dist/__tests__/message.test.js.map +1 -0
  6. package/dist/__tests__/ref.test.d.ts +2 -0
  7. package/dist/__tests__/ref.test.d.ts.map +1 -0
  8. package/dist/__tests__/ref.test.js +68 -0
  9. package/dist/__tests__/ref.test.js.map +1 -0
  10. package/dist/__tests__/schemas.test.d.ts +2 -0
  11. package/dist/__tests__/schemas.test.d.ts.map +1 -0
  12. package/dist/__tests__/schemas.test.js +171 -0
  13. package/dist/__tests__/schemas.test.js.map +1 -0
  14. package/dist/__tests__/snapshot-formatter.test.d.ts +2 -0
  15. package/dist/__tests__/snapshot-formatter.test.d.ts.map +1 -0
  16. package/dist/__tests__/snapshot-formatter.test.js +73 -0
  17. package/dist/__tests__/snapshot-formatter.test.js.map +1 -0
  18. package/dist/constants.d.ts +18 -0
  19. package/dist/constants.d.ts.map +1 -0
  20. package/dist/constants.js +18 -0
  21. package/dist/constants.js.map +1 -0
  22. package/dist/index.d.ts +7 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +7 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/message.d.ts +15 -0
  27. package/dist/message.d.ts.map +1 -0
  28. package/dist/message.js +49 -0
  29. package/dist/message.js.map +1 -0
  30. package/dist/ref.d.ts +18 -0
  31. package/dist/ref.d.ts.map +1 -0
  32. package/dist/ref.js +40 -0
  33. package/dist/ref.js.map +1 -0
  34. package/dist/schemas.d.ts +151 -0
  35. package/dist/schemas.d.ts.map +1 -0
  36. package/dist/schemas.js +63 -0
  37. package/dist/schemas.js.map +1 -0
  38. package/dist/snapshot-formatter.d.ts +12 -0
  39. package/dist/snapshot-formatter.d.ts.map +1 -0
  40. package/dist/snapshot-formatter.js +50 -0
  41. package/dist/snapshot-formatter.js.map +1 -0
  42. package/dist/types/bridge.d.ts +44 -0
  43. package/dist/types/bridge.d.ts.map +1 -0
  44. package/dist/types/bridge.js +6 -0
  45. package/dist/types/bridge.js.map +1 -0
  46. package/dist/types/index.d.ts +5 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/dist/types/index.js +5 -0
  49. package/dist/types/index.js.map +1 -0
  50. package/dist/types/mcp-tools.d.ts +56 -0
  51. package/dist/types/mcp-tools.d.ts.map +1 -0
  52. package/dist/types/mcp-tools.js +5 -0
  53. package/dist/types/mcp-tools.js.map +1 -0
  54. package/dist/types/snapshot.d.ts +32 -0
  55. package/dist/types/snapshot.d.ts.map +1 -0
  56. package/dist/types/snapshot.js +5 -0
  57. package/dist/types/snapshot.js.map +1 -0
  58. package/dist/types/webmcp.d.ts +39 -0
  59. package/dist/types/webmcp.d.ts.map +1 -0
  60. package/dist/types/webmcp.js +6 -0
  61. package/dist/types/webmcp.js.map +1 -0
  62. package/package.json +37 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 kuroko1t
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=message.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/message.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,83 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createMessageId, createRequest, createResponse, createError, isBridgeMessage, } from '../message.js';
3
+ describe('createMessageId', () => {
4
+ it('returns a non-empty string', () => {
5
+ const id = createMessageId();
6
+ expect(typeof id).toBe('string');
7
+ expect(id.length).toBeGreaterThan(0);
8
+ });
9
+ it('returns unique IDs', () => {
10
+ const ids = new Set(Array.from({ length: 100 }, () => createMessageId()));
11
+ expect(ids.size).toBe(100);
12
+ });
13
+ });
14
+ describe('createRequest', () => {
15
+ it('creates a request with correct type', () => {
16
+ const req = createRequest('ping');
17
+ expect(req.type).toBe('request');
18
+ expect(req.method).toBe('ping');
19
+ expect(req.id).toBeTruthy();
20
+ expect(req.timestamp).toBeGreaterThan(0);
21
+ });
22
+ it('includes payload', () => {
23
+ const req = createRequest('navigate', { url: 'https://example.com' });
24
+ expect(req.payload).toEqual({ url: 'https://example.com' });
25
+ });
26
+ it('defaults payload to empty object', () => {
27
+ const req = createRequest('ping');
28
+ expect(req.payload).toEqual({});
29
+ });
30
+ });
31
+ describe('createResponse', () => {
32
+ it('creates a response with correct type', () => {
33
+ const res = createResponse('req-123', 'ping', { pong: true });
34
+ expect(res.type).toBe('response');
35
+ expect(res.id).toBe('req-123');
36
+ expect(res.method).toBe('ping');
37
+ expect(res.payload).toEqual({ pong: true });
38
+ });
39
+ });
40
+ describe('createError', () => {
41
+ it('creates an error with correct structure', () => {
42
+ const err = createError('req-123', 'navigate', 'NOT_FOUND', 'Page not found');
43
+ expect(err.type).toBe('error');
44
+ expect(err.id).toBe('req-123');
45
+ expect(err.method).toBe('navigate');
46
+ expect(err.payload).toEqual({
47
+ code: 'NOT_FOUND',
48
+ message: 'Page not found',
49
+ details: undefined,
50
+ });
51
+ });
52
+ it('includes details when provided', () => {
53
+ const err = createError('req-123', 'navigate', 'ERR', 'fail', { extra: true });
54
+ expect(err.payload.details).toEqual({ extra: true });
55
+ });
56
+ });
57
+ describe('isBridgeMessage', () => {
58
+ it('returns true for valid bridge messages', () => {
59
+ expect(isBridgeMessage({
60
+ id: 'abc',
61
+ type: 'request',
62
+ method: 'ping',
63
+ payload: {},
64
+ timestamp: 123,
65
+ })).toBe(true);
66
+ });
67
+ it('returns false for null', () => {
68
+ expect(isBridgeMessage(null)).toBe(false);
69
+ });
70
+ it('returns false for non-object', () => {
71
+ expect(isBridgeMessage('string')).toBe(false);
72
+ expect(isBridgeMessage(42)).toBe(false);
73
+ });
74
+ it('returns false for missing fields', () => {
75
+ expect(isBridgeMessage({ id: 'abc' })).toBe(false);
76
+ expect(isBridgeMessage({ id: 'abc', type: 'request' })).toBe(false);
77
+ expect(isBridgeMessage({ id: 'abc', type: 'request', method: 'ping' })).toBe(false);
78
+ });
79
+ it('returns false for wrong field types', () => {
80
+ expect(isBridgeMessage({ id: 123, type: 'request', method: 'ping', timestamp: 0 })).toBe(false);
81
+ });
82
+ });
83
+ //# sourceMappingURL=message.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.test.js","sourceRoot":"","sources":["../../src/__tests__/message.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ref.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ref.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { encodeRef, decodeRef, isValidRef, createRefCounter } from '../ref.js';
3
+ describe('encodeRef', () => {
4
+ it('encodes index 1 as @e1', () => {
5
+ expect(encodeRef(1)).toBe('@e1');
6
+ });
7
+ it('encodes large indices', () => {
8
+ expect(encodeRef(999)).toBe('@e999');
9
+ });
10
+ it('throws for index 0', () => {
11
+ expect(() => encodeRef(0)).toThrow('Ref index must be >= 1');
12
+ });
13
+ it('throws for negative index', () => {
14
+ expect(() => encodeRef(-1)).toThrow('Ref index must be >= 1');
15
+ });
16
+ });
17
+ describe('decodeRef', () => {
18
+ it('decodes @e1 to 1', () => {
19
+ expect(decodeRef('@e1')).toBe(1);
20
+ });
21
+ it('decodes @e999 to 999', () => {
22
+ expect(decodeRef('@e999')).toBe(999);
23
+ });
24
+ it('returns null for invalid ref', () => {
25
+ expect(decodeRef('invalid')).toBeNull();
26
+ });
27
+ it('returns null for empty string', () => {
28
+ expect(decodeRef('')).toBeNull();
29
+ });
30
+ it('returns null for partial ref', () => {
31
+ expect(decodeRef('@e')).toBeNull();
32
+ });
33
+ it('returns null for wrong prefix', () => {
34
+ expect(decodeRef('@f1')).toBeNull();
35
+ });
36
+ });
37
+ describe('isValidRef', () => {
38
+ it('returns true for valid refs', () => {
39
+ expect(isValidRef('@e1')).toBe(true);
40
+ expect(isValidRef('@e42')).toBe(true);
41
+ expect(isValidRef('@e100')).toBe(true);
42
+ });
43
+ it('returns false for invalid refs', () => {
44
+ expect(isValidRef('')).toBe(false);
45
+ expect(isValidRef('@e')).toBe(false);
46
+ expect(isValidRef('e1')).toBe(false);
47
+ expect(isValidRef('@f1')).toBe(false);
48
+ expect(isValidRef('@e1x')).toBe(false);
49
+ });
50
+ });
51
+ describe('createRefCounter', () => {
52
+ it('generates sequential refs', () => {
53
+ const counter = createRefCounter();
54
+ expect(counter.next()).toBe('@e1');
55
+ expect(counter.next()).toBe('@e2');
56
+ expect(counter.next()).toBe('@e3');
57
+ });
58
+ it('tracks count', () => {
59
+ const counter = createRefCounter();
60
+ expect(counter.count()).toBe(0);
61
+ counter.next();
62
+ expect(counter.count()).toBe(1);
63
+ counter.next();
64
+ counter.next();
65
+ expect(counter.count()).toBe(3);
66
+ });
67
+ });
68
+ //# sourceMappingURL=ref.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.test.js","sourceRoot":"","sources":["../../src/__tests__/ref.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schemas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,171 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { bridgeMessageSchema, bridgeErrorPayloadSchema, chunkedMessageSchema, navigateToSchema, pageSnapshotSchema, clickSchema, typeTextSchema, selectOptionSchema, listWebMCPToolsSchema, invokeWebMCPToolSchema, screenshotSchema, } from '../schemas.js';
3
+ describe('bridgeMessageSchema', () => {
4
+ it('accepts valid message', () => {
5
+ const result = bridgeMessageSchema.safeParse({
6
+ id: 'abc-123',
7
+ type: 'request',
8
+ method: 'ping',
9
+ payload: {},
10
+ timestamp: Date.now(),
11
+ });
12
+ expect(result.success).toBe(true);
13
+ });
14
+ it('rejects empty id', () => {
15
+ const result = bridgeMessageSchema.safeParse({
16
+ id: '',
17
+ type: 'request',
18
+ method: 'ping',
19
+ payload: {},
20
+ timestamp: Date.now(),
21
+ });
22
+ expect(result.success).toBe(false);
23
+ });
24
+ it('rejects invalid type', () => {
25
+ const result = bridgeMessageSchema.safeParse({
26
+ id: 'abc',
27
+ type: 'invalid',
28
+ method: 'ping',
29
+ payload: {},
30
+ timestamp: Date.now(),
31
+ });
32
+ expect(result.success).toBe(false);
33
+ });
34
+ });
35
+ describe('navigateToSchema', () => {
36
+ it('accepts valid URL', () => {
37
+ const result = navigateToSchema.safeParse({ url: 'https://example.com' });
38
+ expect(result.success).toBe(true);
39
+ });
40
+ it('rejects invalid URL', () => {
41
+ const result = navigateToSchema.safeParse({ url: 'not-a-url' });
42
+ expect(result.success).toBe(false);
43
+ });
44
+ it('accepts optional tabId', () => {
45
+ const result = navigateToSchema.safeParse({ url: 'https://example.com', tabId: 1 });
46
+ expect(result.success).toBe(true);
47
+ });
48
+ });
49
+ describe('clickSchema', () => {
50
+ it('accepts valid ref', () => {
51
+ const result = clickSchema.safeParse({ ref: '@e1', snapshotId: 'snap-123' });
52
+ expect(result.success).toBe(true);
53
+ });
54
+ it('rejects invalid ref format', () => {
55
+ const result = clickSchema.safeParse({ ref: 'invalid', snapshotId: 'snap-123' });
56
+ expect(result.success).toBe(false);
57
+ });
58
+ it('rejects empty snapshotId', () => {
59
+ const result = clickSchema.safeParse({ ref: '@e1', snapshotId: '' });
60
+ expect(result.success).toBe(false);
61
+ });
62
+ });
63
+ describe('typeTextSchema', () => {
64
+ it('accepts valid input', () => {
65
+ const result = typeTextSchema.safeParse({
66
+ ref: '@e5',
67
+ text: 'hello',
68
+ snapshotId: 'snap-1',
69
+ });
70
+ expect(result.success).toBe(true);
71
+ });
72
+ it('accepts clearFirst option', () => {
73
+ const result = typeTextSchema.safeParse({
74
+ ref: '@e5',
75
+ text: 'hello',
76
+ snapshotId: 'snap-1',
77
+ clearFirst: false,
78
+ });
79
+ expect(result.success).toBe(true);
80
+ });
81
+ });
82
+ describe('selectOptionSchema', () => {
83
+ it('accepts valid input', () => {
84
+ const result = selectOptionSchema.safeParse({
85
+ ref: '@e3',
86
+ value: 'option1',
87
+ snapshotId: 'snap-1',
88
+ });
89
+ expect(result.success).toBe(true);
90
+ });
91
+ });
92
+ describe('invokeWebMCPToolSchema', () => {
93
+ it('accepts valid input', () => {
94
+ const result = invokeWebMCPToolSchema.safeParse({
95
+ toolName: 'add_todo',
96
+ args: { text: 'Buy milk' },
97
+ });
98
+ expect(result.success).toBe(true);
99
+ });
100
+ it('rejects empty toolName', () => {
101
+ const result = invokeWebMCPToolSchema.safeParse({
102
+ toolName: '',
103
+ args: {},
104
+ });
105
+ expect(result.success).toBe(false);
106
+ });
107
+ });
108
+ describe('screenshotSchema', () => {
109
+ it('accepts empty object', () => {
110
+ const result = screenshotSchema.safeParse({});
111
+ expect(result.success).toBe(true);
112
+ });
113
+ it('accepts optional params', () => {
114
+ const result = screenshotSchema.safeParse({ tabId: 1, fullPage: true });
115
+ expect(result.success).toBe(true);
116
+ });
117
+ });
118
+ describe('pageSnapshotSchema', () => {
119
+ it('accepts empty object', () => {
120
+ const result = pageSnapshotSchema.safeParse({});
121
+ expect(result.success).toBe(true);
122
+ });
123
+ it('rejects negative maxTokens', () => {
124
+ const result = pageSnapshotSchema.safeParse({ maxTokens: -1 });
125
+ expect(result.success).toBe(false);
126
+ });
127
+ });
128
+ describe('listWebMCPToolsSchema', () => {
129
+ it('accepts empty object', () => {
130
+ const result = listWebMCPToolsSchema.safeParse({});
131
+ expect(result.success).toBe(true);
132
+ });
133
+ });
134
+ describe('chunkedMessageSchema', () => {
135
+ it('accepts valid chunked message', () => {
136
+ const result = chunkedMessageSchema.safeParse({
137
+ id: 'msg-1',
138
+ chunkIndex: 0,
139
+ totalChunks: 3,
140
+ data: 'base64data',
141
+ });
142
+ expect(result.success).toBe(true);
143
+ });
144
+ it('rejects negative chunkIndex', () => {
145
+ const result = chunkedMessageSchema.safeParse({
146
+ id: 'msg-1',
147
+ chunkIndex: -1,
148
+ totalChunks: 3,
149
+ data: 'data',
150
+ });
151
+ expect(result.success).toBe(false);
152
+ });
153
+ });
154
+ describe('bridgeErrorPayloadSchema', () => {
155
+ it('accepts valid error payload', () => {
156
+ const result = bridgeErrorPayloadSchema.safeParse({
157
+ code: 'NOT_FOUND',
158
+ message: 'Page not found',
159
+ });
160
+ expect(result.success).toBe(true);
161
+ });
162
+ it('accepts optional details', () => {
163
+ const result = bridgeErrorPayloadSchema.safeParse({
164
+ code: 'ERR',
165
+ message: 'fail',
166
+ details: { extra: true },
167
+ });
168
+ expect(result.success).toBe(true);
169
+ });
170
+ });
171
+ //# sourceMappingURL=schemas.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.js","sourceRoot":"","sources":["../../src/__tests__/schemas.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=snapshot-formatter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-formatter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/snapshot-formatter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { formatSnapshot, estimateTokens } from '../snapshot-formatter.js';
3
+ describe('formatSnapshot', () => {
4
+ it('formats a simple node', () => {
5
+ const node = { role: 'page', name: 'Test Page' };
6
+ expect(formatSnapshot(node)).toBe('[page "Test Page"]');
7
+ });
8
+ it('formats a node with ref', () => {
9
+ const node = { role: 'button', ref: '@e1', name: 'Submit' };
10
+ expect(formatSnapshot(node)).toBe('[@e1 button "Submit"]');
11
+ });
12
+ it('formats a node with value', () => {
13
+ const node = { role: 'textbox', ref: '@e2', name: 'Email', value: 'test@test.com' };
14
+ expect(formatSnapshot(node)).toBe('[@e2 textbox "Email"] test@test.com');
15
+ });
16
+ it('formats checked state', () => {
17
+ const node = { role: 'checkbox', ref: '@e3', checked: true };
18
+ expect(formatSnapshot(node)).toBe('[@e3 checkbox] (checked)');
19
+ });
20
+ it('formats unchecked state', () => {
21
+ const node = { role: 'checkbox', ref: '@e3', checked: false };
22
+ expect(formatSnapshot(node)).toBe('[@e3 checkbox] (unchecked)');
23
+ });
24
+ it('formats disabled state', () => {
25
+ const node = { role: 'button', ref: '@e4', name: 'Disabled', disabled: true };
26
+ expect(formatSnapshot(node)).toBe('[@e4 button "Disabled"] (disabled)');
27
+ });
28
+ it('formats nested tree', () => {
29
+ const tree = {
30
+ role: 'page',
31
+ name: 'Test',
32
+ children: [
33
+ {
34
+ role: 'nav',
35
+ children: [
36
+ { role: 'link', ref: '@e1', name: 'Home' },
37
+ { role: 'link', ref: '@e2', name: 'About' },
38
+ ],
39
+ },
40
+ {
41
+ role: 'main',
42
+ children: [
43
+ { role: 'button', ref: '@e3', name: 'Click me' },
44
+ ],
45
+ },
46
+ ],
47
+ };
48
+ const result = formatSnapshot(tree);
49
+ const lines = result.split('\n');
50
+ expect(lines[0]).toBe('[page "Test"]');
51
+ expect(lines[1]).toBe(' [nav]');
52
+ expect(lines[2]).toBe(' [@e1 link "Home"]');
53
+ expect(lines[3]).toBe(' [@e2 link "About"]');
54
+ expect(lines[4]).toBe(' [main]');
55
+ expect(lines[5]).toBe(' [@e3 button "Click me"]');
56
+ });
57
+ });
58
+ describe('estimateTokens', () => {
59
+ it('estimates tokens for short text', () => {
60
+ expect(estimateTokens('hello')).toBe(2); // ceil(5/4) = 2
61
+ });
62
+ it('estimates tokens for empty string', () => {
63
+ expect(estimateTokens('')).toBe(0);
64
+ });
65
+ it('estimates tokens for longer text', () => {
66
+ const text = 'a'.repeat(100);
67
+ expect(estimateTokens(text)).toBe(25); // 100/4
68
+ });
69
+ it('rounds up', () => {
70
+ expect(estimateTokens('abc')).toBe(1); // ceil(3/4) = 1
71
+ });
72
+ });
73
+ //# sourceMappingURL=snapshot-formatter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-formatter.test.js","sourceRoot":"","sources":["../../src/__tests__/snapshot-formatter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1E,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAC/D,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC1E,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;QAClG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3E,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5E,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5F,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,IAAI,GAAiB;YACzB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,KAAK;oBACX,QAAQ,EAAE;wBACR,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC1C,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;qBAC5C;iBACF;gBACD;oBACE,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE;wBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE;qBACjD;iBACF;aACF;SACF,CAAC;QAEF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACnB,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Shared constants for WebClaw.
3
+ */
4
+ /** Native Messaging host name (must match manifest) */
5
+ export declare const NATIVE_MESSAGING_HOST = "com.webclaw.bridge";
6
+ /** Extension ID placeholder (set during build/install) */
7
+ export declare const EXTENSION_ID_PLACEHOLDER = "WEBCLAW_EXTENSION_ID";
8
+ /** Maximum Native Messaging payload size (1MB) */
9
+ export declare const NATIVE_MESSAGING_MAX_SIZE: number;
10
+ /** Service Worker keepalive interval in ms (25 seconds, under 30s limit) */
11
+ export declare const KEEPALIVE_INTERVAL_MS = 25000;
12
+ /** Default snapshot token budget */
13
+ export declare const DEFAULT_SNAPSHOT_MAX_TOKENS = 4000;
14
+ /** Content script ↔ page context message channel */
15
+ export declare const PAGE_BRIDGE_CHANNEL = "webclaw-page-bridge";
16
+ /** Side panel message type prefix */
17
+ export declare const SIDE_PANEL_PREFIX = "webclaw-sidepanel";
18
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAE1D,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAE/D,kDAAkD;AAClD,eAAO,MAAM,yBAAyB,QAAc,CAAC;AAErD,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,oCAAoC;AACpC,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Shared constants for WebClaw.
3
+ */
4
+ /** Native Messaging host name (must match manifest) */
5
+ export const NATIVE_MESSAGING_HOST = 'com.webclaw.bridge';
6
+ /** Extension ID placeholder (set during build/install) */
7
+ export const EXTENSION_ID_PLACEHOLDER = 'WEBCLAW_EXTENSION_ID';
8
+ /** Maximum Native Messaging payload size (1MB) */
9
+ export const NATIVE_MESSAGING_MAX_SIZE = 1024 * 1024;
10
+ /** Service Worker keepalive interval in ms (25 seconds, under 30s limit) */
11
+ export const KEEPALIVE_INTERVAL_MS = 25_000;
12
+ /** Default snapshot token budget */
13
+ export const DEFAULT_SNAPSHOT_MAX_TOKENS = 4000;
14
+ /** Content script ↔ page context message channel */
15
+ export const PAGE_BRIDGE_CHANNEL = 'webclaw-page-bridge';
16
+ /** Side panel message type prefix */
17
+ export const SIDE_PANEL_PREFIX = 'webclaw-sidepanel';
18
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAE1D,0DAA0D;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAE/D,kDAAkD;AAClD,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,oCAAoC;AACpC,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAEhD,oDAAoD;AACpD,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAEzD,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './types/index.js';
2
+ export * from './ref.js';
3
+ export * from './schemas.js';
4
+ export * from './constants.js';
5
+ export * from './message.js';
6
+ export * from './snapshot-formatter.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './types/index.js';
2
+ export * from './ref.js';
3
+ export * from './schemas.js';
4
+ export * from './constants.js';
5
+ export * from './message.js';
6
+ export * from './snapshot-formatter.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Message construction utilities.
3
+ */
4
+ import type { BridgeMessage, BridgeRequest, BridgeResponse, BridgeError, BridgeMethod } from './types/bridge.js';
5
+ /** Create a unique message ID */
6
+ export declare function createMessageId(): string;
7
+ /** Create a bridge request message */
8
+ export declare function createRequest(method: BridgeMethod, payload?: unknown): BridgeRequest;
9
+ /** Create a bridge response message */
10
+ export declare function createResponse(requestId: string, method: string, payload?: unknown): BridgeResponse;
11
+ /** Create a bridge error message */
12
+ export declare function createError(requestId: string, method: string, code: string, message: string, details?: unknown): BridgeError;
13
+ /** Type guard for bridge messages */
14
+ export declare function isBridgeMessage(obj: unknown): obj is BridgeMessage;
15
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAED,sCAAsC;AACtC,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,OAAY,GACpB,aAAa,CAQf;AAED,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAY,GACpB,cAAc,CAQhB;AAED,oCAAoC;AACpC,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,OAAO,GAChB,WAAW,CAQb;AAED,qCAAqC;AACrC,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,aAAa,CASlE"}
@@ -0,0 +1,49 @@
1
+ /** Create a unique message ID */
2
+ export function createMessageId() {
3
+ // Use globalThis.crypto.randomUUID (available in Node 19+ and modern browsers)
4
+ if (typeof globalThis.crypto?.randomUUID === 'function') {
5
+ return globalThis.crypto.randomUUID();
6
+ }
7
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
8
+ }
9
+ /** Create a bridge request message */
10
+ export function createRequest(method, payload = {}) {
11
+ return {
12
+ id: createMessageId(),
13
+ type: 'request',
14
+ method,
15
+ payload,
16
+ timestamp: Date.now(),
17
+ };
18
+ }
19
+ /** Create a bridge response message */
20
+ export function createResponse(requestId, method, payload = {}) {
21
+ return {
22
+ id: requestId,
23
+ type: 'response',
24
+ method,
25
+ payload,
26
+ timestamp: Date.now(),
27
+ };
28
+ }
29
+ /** Create a bridge error message */
30
+ export function createError(requestId, method, code, message, details) {
31
+ return {
32
+ id: requestId,
33
+ type: 'error',
34
+ method,
35
+ payload: { code, message, details },
36
+ timestamp: Date.now(),
37
+ };
38
+ }
39
+ /** Type guard for bridge messages */
40
+ export function isBridgeMessage(obj) {
41
+ if (typeof obj !== 'object' || obj === null)
42
+ return false;
43
+ const msg = obj;
44
+ return (typeof msg.id === 'string' &&
45
+ typeof msg.type === 'string' &&
46
+ typeof msg.method === 'string' &&
47
+ typeof msg.timestamp === 'number');
48
+ }
49
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"AAWA,iCAAiC;AACjC,MAAM,UAAU,eAAe;IAC7B,+EAA+E;IAC/E,IAAI,OAAO,UAAU,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,aAAa,CAC3B,MAAoB,EACpB,UAAmB,EAAE;IAErB,OAAO;QACL,EAAE,EAAE,eAAe,EAAE;QACrB,IAAI,EAAE,SAAS;QACf,MAAM;QACN,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,cAAc,CAC5B,SAAiB,EACjB,MAAc,EACd,UAAmB,EAAE;IAErB,OAAO;QACL,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,UAAU;QAChB,MAAM;QACN,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,WAAW,CACzB,SAAiB,EACjB,MAAc,EACd,IAAY,EACZ,OAAe,EACf,OAAiB;IAEjB,OAAO;QACL,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,OAAO;QACb,MAAM;QACN,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;QACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,OAAO,CACL,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAC1B,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ;QAC9B,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAClC,CAAC;AACJ,CAAC"}