gclm-code 1.0.0 → 1.0.1

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 (43) hide show
  1. package/README.md +1 -1
  2. package/bin/gc.js +53 -25
  3. package/bin/install-runtime.js +253 -0
  4. package/package.json +10 -5
  5. package/vendor/manifest.json +92 -0
  6. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/package.json +9 -0
  7. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/bridgeClient.ts +1126 -0
  8. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/browserTools.ts +546 -0
  9. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/index.ts +15 -0
  10. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/mcpServer.ts +96 -0
  11. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/mcpSocketClient.ts +493 -0
  12. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/mcpSocketPool.ts +327 -0
  13. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/toolCalls.ts +301 -0
  14. package/vendor/modules/node_modules/@ant/claude-for-chrome-mcp/src/types.ts +134 -0
  15. package/vendor/modules/node_modules/@ant/computer-use-input/package.json +9 -0
  16. package/vendor/modules/node_modules/@ant/computer-use-input/src/driver-jxa.js +341 -0
  17. package/vendor/modules/node_modules/@ant/computer-use-input/src/driver-swift.swift +417 -0
  18. package/vendor/modules/node_modules/@ant/computer-use-input/src/implementation.js +204 -0
  19. package/vendor/modules/node_modules/@ant/computer-use-input/src/index.js +5 -0
  20. package/vendor/modules/node_modules/@ant/computer-use-mcp/package.json +11 -0
  21. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/deniedApps.ts +553 -0
  22. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/imageResize.ts +108 -0
  23. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/index.ts +69 -0
  24. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/keyBlocklist.ts +153 -0
  25. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/mcpServer.ts +313 -0
  26. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/pixelCompare.ts +171 -0
  27. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/sentinelApps.ts +43 -0
  28. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/subGates.ts +19 -0
  29. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/toolCalls.ts +3872 -0
  30. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/tools.ts +706 -0
  31. package/vendor/modules/node_modules/@ant/computer-use-mcp/src/types.ts +635 -0
  32. package/vendor/modules/node_modules/@ant/computer-use-swift/package.json +9 -0
  33. package/vendor/modules/node_modules/@ant/computer-use-swift/src/driver-jxa.js +108 -0
  34. package/vendor/modules/node_modules/@ant/computer-use-swift/src/implementation.js +706 -0
  35. package/vendor/modules/node_modules/@ant/computer-use-swift/src/index.js +7 -0
  36. package/vendor/modules/node_modules/audio-capture-napi/package.json +8 -0
  37. package/vendor/modules/node_modules/audio-capture-napi/src/index.ts +226 -0
  38. package/vendor/modules/node_modules/image-processor-napi/package.json +11 -0
  39. package/vendor/modules/node_modules/image-processor-napi/src/index.ts +396 -0
  40. package/vendor/modules/node_modules/modifiers-napi/package.json +8 -0
  41. package/vendor/modules/node_modules/modifiers-napi/src/index.ts +79 -0
  42. package/vendor/modules/node_modules/url-handler-napi/package.json +8 -0
  43. package/vendor/modules/node_modules/url-handler-napi/src/index.ts +62 -0
@@ -0,0 +1,134 @@
1
+ export interface Logger {
2
+ info: (message: string, ...args: unknown[]) => void;
3
+ error: (message: string, ...args: unknown[]) => void;
4
+ warn: (message: string, ...args: unknown[]) => void;
5
+ debug: (message: string, ...args: unknown[]) => void;
6
+ silly: (message: string, ...args: unknown[]) => void;
7
+ }
8
+
9
+ export type PermissionMode =
10
+ | "ask"
11
+ | "skip_all_permission_checks"
12
+ | "follow_a_plan";
13
+
14
+ export interface BridgeConfig {
15
+ /** Bridge WebSocket base URL (e.g., wss://bridge.claudeusercontent.com) */
16
+ url: string;
17
+ /** Returns the user's account UUID for the connection path */
18
+ getUserId: () => Promise<string | undefined>;
19
+ /** Returns a valid OAuth token for bridge authentication */
20
+ getOAuthToken: () => Promise<string | undefined>;
21
+ /** Optional dev user ID for local development (bypasses OAuth) */
22
+ devUserId?: string;
23
+ }
24
+
25
+ /** Metadata about a connected Chrome extension instance. */
26
+ export interface ChromeExtensionInfo {
27
+ deviceId: string;
28
+ osPlatform?: string;
29
+ connectedAt: number;
30
+ name?: string;
31
+ }
32
+
33
+ export interface ClaudeForChromeContext {
34
+ serverName: string;
35
+ logger: Logger;
36
+ socketPath: string;
37
+ // Optional dynamic resolver for socket path. When provided, called on each
38
+ // connection attempt to handle runtime conditions (e.g., TMPDIR mismatch).
39
+ getSocketPath?: () => string;
40
+ // Optional resolver returning all available socket paths (for multi-profile support).
41
+ // When provided, a socket pool connects to all sockets and routes by tab ID.
42
+ getSocketPaths?: () => string[];
43
+ clientTypeId: string; // "desktop" | "claude-code"
44
+ onToolCallDisconnected: () => string;
45
+ onAuthenticationError: () => void;
46
+ isDisabled?: () => boolean;
47
+ /** Bridge WebSocket configuration. When provided, uses bridge instead of socket. */
48
+ bridgeConfig?: BridgeConfig;
49
+ /** If set, permission mode is sent to the extension immediately on bridge connection. */
50
+ initialPermissionMode?: PermissionMode;
51
+ /** Optional callback to track telemetry events for bridge connections */
52
+ trackEvent?: <K extends string>(
53
+ eventName: K,
54
+ metadata: Record<string, unknown> | null,
55
+ ) => void;
56
+ /** Called when user pairs with an extension via the browser pairing flow. */
57
+ onExtensionPaired?: (deviceId: string, name: string) => void;
58
+ /** Returns the previously paired deviceId, if any. */
59
+ getPersistedDeviceId?: () => string | undefined;
60
+ /** Called when a remote extension is auto-selected (only option available). */
61
+ onRemoteExtensionWarning?: (ext: ChromeExtensionInfo) => void;
62
+ }
63
+
64
+ /**
65
+ * Map Node's process.platform to the platform string reported by Chrome extensions
66
+ * via navigator.userAgentData.platform.
67
+ */
68
+ export function localPlatformLabel(): string {
69
+ return process.platform === "darwin"
70
+ ? "macOS"
71
+ : process.platform === "win32"
72
+ ? "Windows"
73
+ : "Linux";
74
+ }
75
+
76
+ /** Permission request forwarded from the extension to the desktop for user approval. */
77
+ export interface BridgePermissionRequest {
78
+ /** Links to the pending tool_call */
79
+ toolUseId: string;
80
+ /** Unique ID for this permission request */
81
+ requestId: string;
82
+ /** Tool type, e.g. "navigate", "click", "execute_javascript" */
83
+ toolType: string;
84
+ /** The URL/domain context */
85
+ url: string;
86
+ /** Additional action data (click coordinates, text, etc.) */
87
+ actionData?: Record<string, unknown>;
88
+ }
89
+
90
+ /** Desktop response to a bridge permission request. */
91
+ export interface BridgePermissionResponse {
92
+ requestId: string;
93
+ allowed: boolean;
94
+ }
95
+
96
+ /** Per-call permission overrides, allowing each session to use its own permission state. */
97
+ export interface PermissionOverrides {
98
+ permissionMode: PermissionMode;
99
+ allowedDomains?: string[];
100
+ /** Callback invoked when the extension requests user permission via the bridge. */
101
+ onPermissionRequest?: (request: BridgePermissionRequest) => Promise<boolean>;
102
+ }
103
+
104
+ /** Shared interface for McpSocketClient and McpSocketPool */
105
+ export interface SocketClient {
106
+ ensureConnected(): Promise<boolean>;
107
+ callTool(
108
+ name: string,
109
+ args: Record<string, unknown>,
110
+ permissionOverrides?: PermissionOverrides,
111
+ ): Promise<unknown>;
112
+ isConnected(): boolean;
113
+ disconnect(): void;
114
+ setNotificationHandler(
115
+ handler: (notification: {
116
+ method: string;
117
+ params?: Record<string, unknown>;
118
+ }) => void,
119
+ ): void;
120
+ /** Set permission mode for the current session. Only effective on BridgeClient. */
121
+ setPermissionMode?(
122
+ mode: PermissionMode,
123
+ allowedDomains?: string[],
124
+ ): Promise<void>;
125
+ /** Switch to a different browser. Only available on BridgeClient. */
126
+ switchBrowser?(): Promise<
127
+ | {
128
+ deviceId: string;
129
+ name: string;
130
+ }
131
+ | "no_other_browsers"
132
+ | null
133
+ >;
134
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@ant/computer-use-input",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/index.js"
8
+ }
9
+ }
@@ -0,0 +1,341 @@
1
+ ObjC.import('AppKit')
2
+ ObjC.import('ApplicationServices')
3
+ ObjC.import('stdlib')
4
+
5
+ function main() {
6
+ const argv = $.NSProcessInfo.processInfo.arguments
7
+ if (argv.count < 5) {
8
+ throw new Error('Expected JSON payload argument')
9
+ }
10
+
11
+ const payload = JSON.parse(ObjC.unwrap(argv.objectAtIndex(argv.count - 1)))
12
+ const result = dispatch(payload)
13
+ if (result !== undefined) {
14
+ $.NSFileHandle.fileHandleWithStandardOutput.writeData(
15
+ $(JSON.stringify(result)).dataUsingEncoding($.NSUTF8StringEncoding),
16
+ )
17
+ }
18
+ }
19
+
20
+ function dispatch(payload) {
21
+ switch (payload.op) {
22
+ case 'moveMouse':
23
+ return moveMouse(payload.x, payload.y, payload.dragButton)
24
+ case 'mouseButton':
25
+ return mouseButton(payload.button, payload.action, payload.count)
26
+ case 'mouseLocation':
27
+ return mouseLocation()
28
+ case 'mouseScroll':
29
+ return mouseScroll(payload.amount, payload.axis)
30
+ case 'typeText':
31
+ return typeText(payload.text)
32
+ case 'key':
33
+ return key(payload.key, payload.action)
34
+ case 'keys':
35
+ return keys(payload.keys)
36
+ case 'frontmostAppInfo':
37
+ return frontmostAppInfo()
38
+ default:
39
+ throw new Error(`Unsupported operation: ${payload.op}`)
40
+ }
41
+ }
42
+
43
+ const BUTTON_CODES = {
44
+ left: 0,
45
+ right: 1,
46
+ middle: 2,
47
+ }
48
+
49
+ const BUTTON_EVENT_TYPES = {
50
+ left: {
51
+ down: $.kCGEventLeftMouseDown,
52
+ up: $.kCGEventLeftMouseUp,
53
+ dragged: $.kCGEventLeftMouseDragged,
54
+ },
55
+ right: {
56
+ down: $.kCGEventRightMouseDown,
57
+ up: $.kCGEventRightMouseUp,
58
+ dragged: $.kCGEventRightMouseDragged,
59
+ },
60
+ middle: {
61
+ down: $.kCGEventOtherMouseDown,
62
+ up: $.kCGEventOtherMouseUp,
63
+ dragged: $.kCGEventOtherMouseDragged,
64
+ },
65
+ }
66
+
67
+ const KEY_CODES = {
68
+ a: 0,
69
+ s: 1,
70
+ d: 2,
71
+ f: 3,
72
+ h: 4,
73
+ g: 5,
74
+ z: 6,
75
+ x: 7,
76
+ c: 8,
77
+ v: 9,
78
+ b: 11,
79
+ q: 12,
80
+ w: 13,
81
+ e: 14,
82
+ r: 15,
83
+ y: 16,
84
+ t: 17,
85
+ '1': 18,
86
+ '2': 19,
87
+ '3': 20,
88
+ '4': 21,
89
+ '6': 22,
90
+ '5': 23,
91
+ '=': 24,
92
+ '9': 25,
93
+ '7': 26,
94
+ '-': 27,
95
+ '8': 28,
96
+ '0': 29,
97
+ ']': 30,
98
+ o: 31,
99
+ u: 32,
100
+ '[': 33,
101
+ i: 34,
102
+ p: 35,
103
+ l: 37,
104
+ j: 38,
105
+ "'": 39,
106
+ k: 40,
107
+ ';': 41,
108
+ '\\': 42,
109
+ ',': 43,
110
+ '/': 44,
111
+ n: 45,
112
+ m: 46,
113
+ '.': 47,
114
+ '`': 50,
115
+ return: 36,
116
+ enter: 76,
117
+ tab: 48,
118
+ space: 49,
119
+ delete: 51,
120
+ escape: 53,
121
+ command: 55,
122
+ shift: 56,
123
+ capslock: 57,
124
+ option: 58,
125
+ control: 59,
126
+ rightshift: 60,
127
+ rightoption: 61,
128
+ rightcontrol: 62,
129
+ function: 63,
130
+ f17: 64,
131
+ volumeup: 72,
132
+ volumedown: 73,
133
+ mute: 74,
134
+ f18: 79,
135
+ f19: 80,
136
+ f20: 90,
137
+ f5: 96,
138
+ f6: 97,
139
+ f7: 98,
140
+ f3: 99,
141
+ f8: 100,
142
+ f9: 101,
143
+ f11: 103,
144
+ f13: 105,
145
+ f16: 106,
146
+ f14: 107,
147
+ f10: 109,
148
+ f12: 111,
149
+ f15: 113,
150
+ help: 114,
151
+ home: 115,
152
+ pageup: 116,
153
+ forwarddelete: 117,
154
+ f4: 118,
155
+ end: 119,
156
+ f2: 120,
157
+ pagedown: 121,
158
+ f1: 122,
159
+ left: 123,
160
+ right: 124,
161
+ down: 125,
162
+ up: 126,
163
+ }
164
+
165
+ const MODIFIER_FLAGS = {
166
+ command: $.kCGEventFlagMaskCommand,
167
+ shift: $.kCGEventFlagMaskShift,
168
+ option: $.kCGEventFlagMaskAlternate,
169
+ control: $.kCGEventFlagMaskControl,
170
+ }
171
+
172
+ function point(x, y) {
173
+ return $.CGPointMake(x, y)
174
+ }
175
+
176
+ function postMouseEvent(type, location, button, clickState) {
177
+ const event = $.CGEventCreateMouseEvent(
178
+ null,
179
+ type,
180
+ location,
181
+ BUTTON_CODES[button] ?? 0,
182
+ )
183
+ if (clickState !== undefined) {
184
+ $.CGEventSetIntegerValueField(event, $.kCGMouseEventClickState, clickState)
185
+ }
186
+ $.CGEventPost($.kCGHIDEventTap, event)
187
+ $.CFRelease(event)
188
+ }
189
+
190
+ function currentMouseLocation() {
191
+ const event = $.CGEventCreate(null)
192
+ const location = $.CGEventGetLocation(event)
193
+ $.CFRelease(event)
194
+ return location
195
+ }
196
+
197
+ function moveMouse(x, y, dragButton) {
198
+ const location = point(x, y)
199
+ if (dragButton) {
200
+ const types = BUTTON_EVENT_TYPES[dragButton]
201
+ postMouseEvent(types?.dragged ?? $.kCGEventLeftMouseDragged, location, dragButton)
202
+ return true
203
+ }
204
+ postMouseEvent($.kCGEventMouseMoved, location, 'left')
205
+ return true
206
+ }
207
+
208
+ function mouseButton(button, action, count) {
209
+ const location = currentMouseLocation()
210
+ const types = BUTTON_EVENT_TYPES[button]
211
+ if (!types) {
212
+ throw new Error(`Unsupported mouse button: ${button}`)
213
+ }
214
+ const normalizedAction =
215
+ action === 'press' ? 'down' : action === 'release' ? 'up' : action
216
+ if (normalizedAction === 'click') {
217
+ const clickCount = Math.max(1, Number(count) || 1)
218
+ for (let i = 1; i <= clickCount; i++) {
219
+ postMouseEvent(types.down, location, button, i)
220
+ postMouseEvent(types.up, location, button, i)
221
+ }
222
+ return true
223
+ }
224
+ const type = types[normalizedAction]
225
+ if (type === undefined) {
226
+ throw new Error(`Unsupported mouse action: ${action}`)
227
+ }
228
+ postMouseEvent(type, location, button, count)
229
+ return true
230
+ }
231
+
232
+ function mouseLocation() {
233
+ const location = currentMouseLocation()
234
+ return { x: Math.round(location.x), y: Math.round(location.y) }
235
+ }
236
+
237
+ function mouseScroll(amount, axis) {
238
+ const vertical = axis === 'y' || axis === 'vertical' ? amount : 0
239
+ const horizontal = axis === 'x' || axis === 'horizontal' ? amount : 0
240
+ const event = $.CGEventCreateScrollWheelEvent(
241
+ null,
242
+ $.kCGScrollEventUnitPixel,
243
+ 2,
244
+ vertical,
245
+ horizontal,
246
+ )
247
+ $.CGEventPost($.kCGHIDEventTap, event)
248
+ $.CFRelease(event)
249
+ return true
250
+ }
251
+
252
+ function typeText(text) {
253
+ const source = $.CGEventSourceCreate($.kCGEventSourceStateHIDSystemState)
254
+ for (const ch of text) {
255
+ const down = $.CGEventCreateKeyboardEvent(source, 0, true)
256
+ $.CGEventKeyboardSetUnicodeString(down, 1, $(ch))
257
+ $.CGEventPost($.kCGHIDEventTap, down)
258
+ $.CFRelease(down)
259
+
260
+ const up = $.CGEventCreateKeyboardEvent(source, 0, false)
261
+ $.CGEventKeyboardSetUnicodeString(up, 1, $(ch))
262
+ $.CGEventPost($.kCGHIDEventTap, up)
263
+ $.CFRelease(up)
264
+ }
265
+ $.CFRelease(source)
266
+ return true
267
+ }
268
+
269
+ function key(name, action) {
270
+ const keyCode = KEY_CODES[String(name).toLowerCase()]
271
+ if (keyCode === undefined) {
272
+ throw new Error(`Unsupported key: ${name}`)
273
+ }
274
+ const normalizedAction = String(action ?? 'press').toLowerCase()
275
+ if (
276
+ normalizedAction !== 'down' &&
277
+ normalizedAction !== 'up' &&
278
+ normalizedAction !== 'press' &&
279
+ normalizedAction !== 'release'
280
+ ) {
281
+ throw new Error(`Unsupported key action: ${action}`)
282
+ }
283
+ const isDown = normalizedAction === 'down' || normalizedAction === 'press'
284
+ const event = $.CGEventCreateKeyboardEvent(null, keyCode, isDown)
285
+ $.CGEventPost($.kCGHIDEventTap, event)
286
+ $.CFRelease(event)
287
+ return true
288
+ }
289
+
290
+ function keys(names) {
291
+ let flags = 0
292
+ for (const name of names) {
293
+ const normalized = String(name).toLowerCase()
294
+ const keyCode = KEY_CODES[normalized]
295
+ if (keyCode === undefined) {
296
+ throw new Error(`Unsupported key: ${name}`)
297
+ }
298
+ const event = $.CGEventCreateKeyboardEvent(null, keyCode, true)
299
+ const modifierFlag = MODIFIER_FLAGS[normalized]
300
+ if (modifierFlag) {
301
+ flags |= modifierFlag
302
+ $.CGEventSetFlags(event, flags)
303
+ } else if (flags) {
304
+ $.CGEventSetFlags(event, flags)
305
+ }
306
+ $.CGEventPost($.kCGHIDEventTap, event)
307
+ $.CFRelease(event)
308
+ }
309
+
310
+ for (const name of [...names].reverse()) {
311
+ const normalized = String(name).toLowerCase()
312
+ const keyCode = KEY_CODES[normalized]
313
+ const event = $.CGEventCreateKeyboardEvent(null, keyCode, false)
314
+ const modifierFlag = MODIFIER_FLAGS[normalized]
315
+ if (modifierFlag) {
316
+ flags &= ~modifierFlag
317
+ $.CGEventSetFlags(event, flags)
318
+ } else if (flags) {
319
+ $.CGEventSetFlags(event, flags)
320
+ }
321
+ $.CGEventPost($.kCGHIDEventTap, event)
322
+ $.CFRelease(event)
323
+ }
324
+ return true
325
+ }
326
+
327
+ function frontmostAppInfo() {
328
+ const workspace = $.NSWorkspace.sharedWorkspace
329
+ const app = workspace.frontmostApplication
330
+ if (!app) {
331
+ return null
332
+ }
333
+ const name = ObjC.unwrap(app.localizedName)
334
+ return {
335
+ bundleId: ObjC.unwrap(app.bundleIdentifier),
336
+ appName: name,
337
+ name,
338
+ }
339
+ }
340
+
341
+ main()