@ceki/n8n-nodes-ceki 0.2.6 → 0.2.7

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.
@@ -39,6 +39,21 @@ var CekiApi = class {
39
39
  required: true
40
40
  }
41
41
  ];
42
+ this.authenticate = {
43
+ type: "generic",
44
+ properties: {
45
+ headers: {
46
+ Authorization: "=Bearer {{$credentials?.token}}"
47
+ }
48
+ }
49
+ };
50
+ this.test = {
51
+ request: {
52
+ baseURL: "https://api.ceki.me",
53
+ url: "/api/browsers/search",
54
+ method: "GET"
55
+ }
56
+ };
42
57
  }
43
58
  };
44
59
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../credentials/CekiApi.credentials.ts"],
4
- "sourcesContent": ["import type { ICredentialType, INodeProperties } from 'n8n-workflow';\n\n/**\n * Ceki agent token (ag_...). Authorizes every Ceki node.\n * Get it from the Ceki panel \u2192 agent profile \u2192 API key.\n */\nexport class CekiApi implements ICredentialType {\n\tname = 'cekiApi';\n\tdisplayName = 'Ceki API';\n\tdocumentationUrl = 'https://browser.ceki.me/docs#api-key';\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'token',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'Agent token (ag_...). [Get your API key \u2192](https://browser.ceki.me/docs#api-key)',\n\t\t\trequired: true,\n\t\t},\n\t];\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,IAAM,UAAN,MAAyC;AAAA,EAAzC;AACN,gBAAO;AACP,uBAAc;AACd,4BAAmB;AACnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa,EAAE,UAAU,KAAK;AAAA,QAC9B,SAAS;AAAA,QACT,aACC;AAAA,QACD,UAAU;AAAA,MACX;AAAA,IACD;AAAA;AACD;",
4
+ "sourcesContent": ["import type {\n\tIAuthenticateGeneric,\n\tICredentialTestRequest,\n\tICredentialType,\n\tINodeProperties,\n} from 'n8n-workflow';\n\n/**\n * Ceki agent token (ag_...). Authorizes every Ceki node.\n * Get it from the Ceki panel \u2192 agent profile \u2192 API key.\n */\nexport class CekiApi implements ICredentialType {\n\tname = 'cekiApi';\n\tdisplayName = 'Ceki API';\n\tdocumentationUrl = 'https://browser.ceki.me/docs#api-key';\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'token',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'Agent token (ag_...). [Get your API key \u2192](https://browser.ceki.me/docs#api-key)',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{$credentials?.token}}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tbaseURL: 'https://api.ceki.me',\n\t\t\turl: '/api/browsers/search',\n\t\t\tmethod: 'GET',\n\t\t},\n\t};\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,IAAM,UAAN,MAAyC;AAAA,EAAzC;AACN,gBAAO;AACP,uBAAc;AACd,4BAAmB;AACnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa,EAAE,UAAU,KAAK;AAAA,QAC9B,SAAS;AAAA,QACT,aACC;AAAA,QACD,UAAU;AAAA,MACX;AAAA,IACD;AAEA,wBAAqC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,QACX,SAAS;AAAA,UACR,eAAe;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAEA,gBAA+B;AAAA,MAC9B,SAAS;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ;AAAA,MACT;AAAA,IACD;AAAA;AACD;",
6
6
  "names": []
7
7
  }
package/dist/index.js CHANGED
@@ -1348,6 +1348,21 @@ var CekiApi = class {
1348
1348
  required: true
1349
1349
  }
1350
1350
  ];
1351
+ this.authenticate = {
1352
+ type: "generic",
1353
+ properties: {
1354
+ headers: {
1355
+ Authorization: "=Bearer {{$credentials?.token}}"
1356
+ }
1357
+ }
1358
+ };
1359
+ this.test = {
1360
+ request: {
1361
+ baseURL: "https://api.ceki.me",
1362
+ url: "/api/browsers/search",
1363
+ method: "GET"
1364
+ }
1365
+ };
1351
1366
  }
1352
1367
  };
1353
1368
 
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.ts", "../lib/ceki-client.ts", "../nodes/BrowserCeki/BrowserCeki.node.ts", "../lib/contract-client.ts", "../nodes/CekiContract/CekiContract.node.ts", "../nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node.ts", "../nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node.ts", "../credentials/CekiApi.credentials.ts"],
4
- "sourcesContent": ["import { BrowserCeki } from './nodes/BrowserCeki/BrowserCeki.node';\nimport { CekiContract } from './nodes/CekiContract/CekiContract.node';\nimport { CekiCaptchaScrape } from './nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node';\nimport { CekiScreenshotGeo } from './nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node';\nimport { CekiApi } from './credentials/CekiApi.credentials';\n\nexport const nodes = [\n\tBrowserCeki,\n\tCekiContract,\n\tCekiCaptchaScrape,\n\tCekiScreenshotGeo,\n];\n\nexport const credentials = [\n\tCekiApi,\n];\n", "/**\n * Minimal Ceki browser client \u2014 uses only native WebSocket + fetch (Node 22 globals).\n * Zero npm imports (no ws, no mime-types, no node built-in modules).\n *\n * Timeout management: uses AbortSignal.timeout() instead of restricted\n * setTimeout/clearTimeout globals to satisfy the n8n community-nodes\n * package scanner (no-restricted-globals rule).\n */\n\n// \u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface BrowserOption {\n\tschedule_id: number;\n\tgeo?: string;\n\tprice_per_min: number;\n\tonline: boolean;\n\trating?: number | null;\n}\n\nexport interface Match {\n\tsession_id: string;\n\tschedule_id: number;\n\tevent_id?: string | null;\n\tchat_topic_id?: string | null;\n\tprovider_user_id?: number | null;\n\tbrowser_info?: Record<string, unknown>;\n}\n\nexport interface RentOptions {\n\tmode?: 'main' | 'incognito';\n}\n\nexport interface ScreenshotOptions {\n\tformat?: 'png' | 'base64';\n\tfullPage?: boolean;\n}\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction jsonParse(raw: string): unknown {\n\ttry { return JSON.parse(raw); } catch { return null; }\n}\n\n// \u2500\u2500 Client \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class CekiClient {\n\tprivate _ws: WebSocket | null = null;\n\tprivate _connected = false;\n\tprivate _pendingRents = new Map<string, {\n\t\tresolve: (m: Match) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _pendingResumes = new Map<string, {\n\t\tresolve: (m: Match) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _pendingCdp = new Map<number, {\n\t\tresolve: (v: unknown) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _cdpCounter = 1;\n\t_activeSessions = new Map<string, CekiBrowser>();\n\tprivate _connectReject: ((e: Error) => void) | null = null;\n\tprivate _closed = false;\n\n\tconstructor(\n\t\tprivate _token: string,\n\t\tprivate _relayUrl = 'wss://browser.ceki.me/ws/agent',\n\t\tprivate _apiUrl = 'https://api.ceki.me',\n\t) {}\n\n\t/** Connect to the relay WebSocket. */\n\tasync connect(): Promise<void> {\n\t\tif (this._connected) return;\n\t\tconst protocols = [`bearer.${this._token}`];\n\t\tthis._ws = new WebSocket(this._relayUrl, protocols);\n\t\tthis._ws.onopen = () => {\n\t\t\tthis._connected = true;\n\t\t};\n\t\tthis._ws.onmessage = (ev: MessageEvent) => {\n\t\t\tthis._handleMessage(ev.data);\n\t\t};\n\t\tthis._ws.onclose = (ev: CloseEvent) => {\n\t\t\tthis._connected = false;\n\t\t\tif ((ev.code === 4401 || ev.code === 4403) && this._connectReject) {\n\t\t\t\tthis._connectReject(new Error(`Auth failed: ${ev.reason || String(ev.code)}`));\n\t\t\t\tthis._connectReject = null;\n\t\t\t}\n\t\t};\n\t\tthis._ws.onerror = () => {\n\t\t\tif (!this._connected && this._connectReject) {\n\t\t\t\tthis._connectReject(new Error('WebSocket connection failed'));\n\t\t\t\tthis._connectReject = null;\n\t\t\t}\n\t\t};\n\t\tif (this._ws.readyState === WebSocket.CONNECTING) {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tif (!this._ws) { reject(new Error('No WebSocket')); return; }\n\t\t\t\tthis._connectReject = reject;\n\t\t\t\tthis._ws!.onopen = () => {\n\t\t\t\t\tthis._connected = true;\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t_sendRaw(msg: Record<string, unknown>): void {\n\t\tif (!this._ws || this._ws.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new Error('WebSocket not connected');\n\t\t}\n\t\tthis._ws.send(JSON.stringify(msg));\n\t}\n\n\t/** Search for available browser providers (HTTP GET). */\n\tasync search(filters?: Record<string, unknown>, limit?: number): Promise<BrowserOption[]> {\n\t\tconst params = new URLSearchParams();\n\t\tif (limit != null) params.set('limit', String(limit));\n\t\tif (filters) {\n\t\t\tfor (const [k, v] of Object.entries(filters)) {\n\t\t\t\tif (v != null) params.set(k, String(v));\n\t\t\t}\n\t\t}\n\t\tconst resp = await fetch(`${this._apiUrl}/api/browsers/search?${params}`, {\n\t\t\theaders: { Authorization: `Bearer ${this._token}` },\n\t\t});\n\t\tif (!resp.ok) throw new Error(`Search failed: ${resp.status}`);\n\t\tconst body = (await resp.json()) as Record<string, unknown>;\n\t\tconst data = (body.data ?? body) as unknown[];\n\t\treturn Array.isArray(data) ? data as BrowserOption[] : [];\n\t}\n\n\t/** Rent a browser by schedule_id. */\n\tasync rent(scheduleId: number, opts?: RentOptions): Promise<CekiBrowser> {\n\t\tconst msg: Record<string, unknown> = { type: 'rent', browser_id: scheduleId };\n\t\tif (opts?.mode) msg.mode = opts.mode;\n\t\tthis._sendRaw(msg);\n\t\treturn this._awaitRent(`rent:${scheduleId}`, scheduleId, 90000);\n\t}\n\n\t/** Resume an existing session. */\n\tasync resume(sessionId: string): Promise<CekiBrowser> {\n\t\tthis._sendRaw({ type: 'resume', session_id: sessionId });\n\t\treturn this._awaitResume(sessionId);\n\t}\n\n\t/** Close the WS connection \u2014 session stays alive in grace. */\n\tdisconnect(): void {\n\t\tthis._closed = true;\n\t\tthis._activeSessions.clear();\n\t\tthis._pendingRents.clear();\n\t\tthis._pendingResumes.clear();\n\t\tthis._closeWs();\n\t}\n\n\t/** Close everything. */\n\tclose(): void {\n\t\tthis.disconnect();\n\t}\n\n\t// \u2500\u2500 private \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate _awaitRent(key: string, scheduleId: number, timeoutMs: number): Promise<CekiBrowser> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(timeoutMs);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingRents.delete(key);\n\t\t\t\treject(new Error('Rent timed out'));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingRents.set(key, {\n\t\t\t\tresolve: (match: Match) => {\n\t\t\t\t\tconst browser = new CekiBrowser(this, match);\n\t\t\t\t\tthis._activeSessions.set(browser.sessionId, browser);\n\t\t\t\t\tresolve(browser);\n\t\t\t\t},\n\t\t\t\treject: (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _awaitResume(sessionId: string): Promise<CekiBrowser> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(10000);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingResumes.delete(sessionId);\n\t\t\t\treject(new Error('Resume timed out'));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingResumes.set(sessionId, {\n\t\t\t\tresolve: (match: Match) => {\n\t\t\t\t\tconst browser = new CekiBrowser(this, match);\n\t\t\t\t\tthis._activeSessions.set(browser.sessionId, browser);\n\t\t\t\t\tresolve(browser);\n\t\t\t\t},\n\t\t\t\treject: (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _closeWs(): void {\n\t\tif (this._ws) {\n\t\t\ttry { this._ws.onopen = null; this._ws.onmessage = null; this._ws.onclose = null; this._ws.onerror = null; this._ws.close(); } catch { /* ignore */ }\n\t\t\tthis._ws = null;\n\t\t}\n\t}\n\n\tprivate _handleMessage(data: unknown): void {\n\t\tconst msg = jsonParse(String(data)) as Record<string, unknown> | null;\n\t\tif (!msg || typeof msg !== 'object') return;\n\t\tconst type = String(msg.type ?? '');\n\t\tconst sid = msg.session_id ? String(msg.session_id) : null;\n\n\t\tswitch (type) {\n\t\t\tcase 'pong':\n\t\t\tcase 'rent_pending':\n\t\t\t\tbreak;\n\t\t\tcase 'match':\n\t\t\t\tthis._onMatch(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'rent.error':\n\t\t\t\tthis._onRentError(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'resume_ok':\n\t\t\t\tthis._onResumeOk(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'resume_failed':\n\t\t\t\tthis._onResumeFailed(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'cdp_response':\n\t\t\t\tif (sid) this._onCdpResponse(sid, msg);\n\t\t\t\tbreak;\n\t\t\tcase 'session.ended':\n\t\t\t\tif (sid) {\n\t\t\t\t\tthis._activeSessions.delete(sid);\n\t\t\t\t\tconst b = this._activeSessions.get(sid);\n\t\t\t\t\tif (b) (b as any)._ended = String(msg.reason ?? 'ended');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate _onMatch(msg: Record<string, unknown>): void {\n\t\tconst scheduleId = Number(msg.schedule_id ?? 0);\n\t\tconst eventId = msg.event_id ? String(msg.event_id) : null;\n\t\tlet pending = this._pendingRents.get(`event:${eventId}`);\n\t\tif (!pending) pending = this._pendingRents.get(`rent:${scheduleId}`);\n\t\tif (pending) {\n\t\t\tthis._pendingRents.delete(`event:${eventId}`);\n\t\t\tthis._pendingRents.delete(`rent:${scheduleId}`);\n\t\t\tpending.resolve({\n\t\t\t\tsession_id: String(msg.session_id ?? ''),\n\t\t\t\tschedule_id: scheduleId,\n\t\t\t\tevent_id: eventId,\n\t\t\t\tchat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,\n\t\t\t\tprovider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,\n\t\t\t\tbrowser_info: (msg.browser_info ?? {}) as Record<string, unknown>,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate _onRentError(msg: Record<string, unknown>): void {\n\t\tconst code = String(msg.code ?? '');\n\t\tconst message = String(msg.message ?? '');\n\t\tfor (const [key, pending] of this._pendingRents) {\n\t\t\tthis._pendingRents.delete(key);\n\t\t\tpending.reject(new Error(message || `Rent error: ${code}`));\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate _onResumeOk(msg: Record<string, unknown>): void {\n\t\tconst sessionId = String(msg.session_id ?? '');\n\t\tconst pending = this._pendingResumes.get(sessionId);\n\t\tif (!pending) return;\n\t\tthis._pendingResumes.delete(sessionId);\n\t\tpending.resolve({\n\t\t\tsession_id: sessionId,\n\t\t\tschedule_id: Number(msg.schedule_id ?? 0),\n\t\t\tevent_id: msg.event_id ? String(msg.event_id) : null,\n\t\t\tchat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,\n\t\t\tprovider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,\n\t\t\tbrowser_info: (msg.browser_info ?? {}) as Record<string, unknown>,\n\t\t});\n\t}\n\n\tprivate _onResumeFailed(msg: Record<string, unknown>): void {\n\t\tconst sessionId = String(msg.session_id ?? '');\n\t\tconst pending = this._pendingResumes.get(sessionId);\n\t\tif (!pending) return;\n\t\tthis._pendingResumes.delete(sessionId);\n\t\tpending.reject(new Error(String(msg.reason ?? 'Resume failed')));\n\t}\n\n\tprivate _onCdpResponse(sessionId: string, msg: Record<string, unknown>): void {\n\t\tconst browser = this._activeSessions.get(sessionId);\n\t\tif (!browser) return;\n\t\tconst id = Number(msg.id ?? 0);\n\t\tconst pending = this._pendingCdp.get(id);\n\t\tif (!pending) return;\n\t\tthis._pendingCdp.delete(id);\n\t\tif (msg.error) {\n\t\t\tpending.reject(new Error(String((msg.error as Record<string, unknown>).message ?? 'CDP error')));\n\t\t} else {\n\t\t\tpending.resolve(msg.result);\n\t\t}\n\t}\n}\n\n// \u2500\u2500 Browser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class CekiBrowser {\n\treadonly sessionId: string;\n\treadonly scheduleId: number;\n\treadonly chatTopicId: string | null;\n\treadonly browserInfo: Record<string, unknown>;\n\treadonly providerUserId: number | null;\n\n\tprivate _client: CekiClient;\n\tprivate _cdpId = 1;\n\t_pendingCdp = new Map<number, { resolve: (v: unknown) => void; reject: (e: Error) => void }>();\n\n\tconstructor(client: CekiClient, match: Match) {\n\t\tthis._client = client;\n\t\tthis.sessionId = match.session_id;\n\t\tthis.scheduleId = match.schedule_id;\n\t\tthis.chatTopicId = match.chat_topic_id ?? null;\n\t\tthis.browserInfo = match.browser_info ?? {};\n\t\tthis.providerUserId = match.provider_user_id ?? null;\n\t}\n\n\t/** Send a CDP command. Uses AbortSignal.timeout() (no restricted setTimeout global). */\n\tasync send(method: string, params?: Record<string, unknown>, timeoutMs = 30000): Promise<unknown> {\n\t\tconst id = this._cdpId++;\n\t\tconst msg = { type: 'cdp', session_id: this.sessionId, id, method, params: params ?? {} };\n\t\tthis._client._sendRaw(msg);\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(timeoutMs);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingCdp.delete(id);\n\t\t\t\treject(new Error(`CDP ${method} timed out after ${timeoutMs}ms`));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingCdp.set(id, {\n\t\t\t\tresolve: (v) => { resolve(v); },\n\t\t\t\treject: (e) => { reject(e); },\n\t\t\t});\n\t\t});\n\t}\n\n\tasync navigate(url: string, timeoutMs?: number): Promise<void> {\n\t\tawait this.send('Page.navigate', { url }, timeoutMs);\n\t}\n\n\tasync click(x: number, y: number): Promise<void> {\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mousePressed', x, y, button: 'left', clickCount: 1 });\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x, y, button: 'left', clickCount: 1 });\n\t}\n\n\tasync type(text: string): Promise<void> {\n\t\tawait this.send('Ceki.typeText', { text });\n\t}\n\n\tasync scroll(deltaY: number): Promise<void> {\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mouseWheel', x: 0, y: 0, deltaX: 0, deltaY });\n\t}\n\n\tasync screenshot(opts?: ScreenshotOptions): Promise<{ data: string } | Buffer> {\n\t\tconst format = opts?.format ?? 'base64';\n\t\tconst fullPage = opts?.fullPage ?? false;\n\t\tlet clip: Record<string, number> | undefined;\n\t\tif (fullPage) {\n\t\t\tconst metrics = await this.send('Page.getLayoutMetrics') as Record<string, unknown> | null;\n\t\t\tconst contentSize = metrics?.contentSize as Record<string, number> | undefined;\n\t\t\tif (contentSize) {\n\t\t\t\tclip = { x: 0, y: 0, width: Number(contentSize.width ?? 1920), height: Math.min(Number(contentSize.height ?? 1080), 16384), scale: 1 };\n\t\t\t}\n\t\t}\n\t\tconst result = await this.send('Page.captureScreenshot', { format: 'png', ...(clip ? { clip } : {}) }) as Record<string, unknown> | null;\n\t\tconst data = String(result?.data ?? '');\n\t\tif (format === 'png') {\n\t\t\treturn Buffer.from(data, 'base64');\n\t\t}\n\t\treturn { data };\n\t}\n\n\tasync snapshot(): Promise<{ screenshot: string; ts: Date }> {\n\t\tconst ssResult = await this.screenshot({ format: 'base64' }) as { data: string };\n\t\treturn { screenshot: ssResult.data, ts: new Date() };\n\t}\n\n\tasync upload(selector: string, buf: Buffer, filename = 'file'): Promise<Record<string, unknown>> {\n\t\tconst b64 = buf.toString('base64');\n\t\tconst size = buf.length;\n\t\tconst mime = 'application/octet-stream';\n\t\tconst expression = `(function(){\n\t\t\tvar input = document.querySelector(${JSON.stringify(selector)});\n\t\t\tif (!input) return JSON.stringify({ok:false,error:'Element not found'});\n\t\t\tvar b = atob(${JSON.stringify(b64)});\n\t\t\tvar u = new Uint8Array(b.length);\n\t\t\tfor (var i = 0; i < b.length; i++) u[i] = b.charCodeAt(i);\n\t\t\tvar f = new File([u], ${JSON.stringify(filename)}, {type: ${JSON.stringify(mime)}});\n\t\t\tvar dt = new DataTransfer(); dt.items.add(f);\n\t\t\tinput.files = dt.files;\n\t\t\tinput.dispatchEvent(new Event('change',{bubbles:true}));\n\t\t\treturn JSON.stringify({ok:true,filename:${JSON.stringify(filename)},size:${size}});\n\t\t})()`;\n\t\tconst result = await this.send('Runtime.evaluate', { expression, returnByValue: true }) as Record<string, unknown> | null;\n\t\ttry {\n\t\t\tawait this.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'Escape', code: 'Escape', windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });\n\t\t\tawait this.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'Escape', code: 'Escape', windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });\n\t\t} catch { /* ignore */ }\n\t\tconst resultObj = result?.result as Record<string, unknown> | undefined;\n\t\tif (resultObj?.value) return JSON.parse(String(resultObj.value)) as Record<string, unknown>;\n\t\treturn { ok: true, filename, size };\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.send('Ceki.close', {}).catch(() => {});\n\t\tthis._client._activeSessions.delete(this.sessionId);\n\t}\n}\n", "import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { CekiClient } from '../../lib/ceki-client';\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => {\n\tAbortSignal.timeout(ms).addEventListener('abort', () => resolve(), { once: true });\n});\n\n/**\n * Browser Ceki \u2014 one node, many operations.\n * Uses native WebSocket (not the ws library) \u2014 zero external runtime deps.\n */\nexport class BrowserCeki implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki',\n\t\tname: 'browserCeki',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '={{ \"Ceki: \" + $operation }}',\n\t\tdescription: 'Rent a real human browser and control it: rent, navigate, click, type, screenshot, solve captchas, and more',\n\t\tdefaults: { name: 'Browser Ceki' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'operation',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'rent',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Rent', value: 'rent' },\n\t\t\t\t\t{ name: 'Navigate', value: 'navigate' },\n\t\t\t\t\t{ name: 'Click', value: 'click' },\n\t\t\t\t\t{ name: 'Type', value: 'type' },\n\t\t\t\t\t{ name: 'Scroll', value: 'scroll' },\n\t\t\t\t\t{ name: 'Screenshot', value: 'screenshot' },\n\t\t\t\t\t{ name: 'Snapshot', value: 'snapshot' },\n\t\t\t\t\t{ name: 'Wait', value: 'wait' },\n\t\t\t\t\t{ name: 'Wait for Selector', value: 'waitForSelector' },\n\t\t\t\t\t{ name: 'Upload', value: 'upload' },\n\t\t\t\t\t{ name: 'Close', value: 'close' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t// === Rent: rental parameters ===\n\t\t\t{\n\t\t\t\tdisplayName: 'Schedule ID',\n\t\t\t\tname: 'scheduleId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: '0 \u2014 search by the filters below',\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Geo',\n\t\t\t\tname: 'geo',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'RU, EE, US\u2026',\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Max $/min',\n\t\t\t\tname: 'maxPrice',\n\t\t\t\ttype: 'number',\n\t\t\t\ttypeOptions: { numberPrecision: 4 },\n\t\t\t\tdefault: 0.02,\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Min rating',\n\t\t\t\tname: 'minRating',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Profile mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'main',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'main', value: 'main' },\n\t\t\t\t\t{ name: 'incognito', value: 'incognito' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t// === Operations: session_id ===\n\t\t\t{\n\t\t\t\tdisplayName: 'Session ID',\n\t\t\t\tname: 'sessionId',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '={{ $json.session_id }}',\n\t\t\t\tdescription: 'From the Rent operation',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\toperation: ['navigate', 'click', 'type', 'scroll', 'screenshot', 'snapshot', 'wait', 'waitForSelector', 'upload', 'close'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['navigate'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'X',\n\t\t\t\tname: 'x',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['click'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Y',\n\t\t\t\tname: 'y',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['click'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: { show: { operation: ['type'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Delta Y',\n\t\t\t\tname: 'deltaY',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: -300,\n\t\t\t\tdisplayOptions: { show: { operation: ['scroll'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Format',\n\t\t\t\tname: 'format',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'png',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'PNG (binary)', value: 'png' },\n\t\t\t\t\t{ name: 'Base64', value: 'base64' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['screenshot'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Full page',\n\t\t\t\tname: 'fullPage',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdisplayOptions: { show: { operation: ['screenshot'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Milliseconds',\n\t\t\t\tname: 'ms',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 1000,\n\t\t\t\ttypeOptions: { minValue: 0 },\n\t\t\t\tdescription: 'Fixed delay on the active session',\n\t\t\t\tdisplayOptions: { show: { operation: ['wait'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'CSS Selector',\n\t\t\t\tname: 'waitSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tplaceholder: 'e.g. .results, #content, table tr',\n\t\t\t\tdisplayOptions: { show: { operation: ['waitForSelector'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Timeout (ms)',\n\t\t\t\tname: 'waitTimeout',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 30000,\n\t\t\t\tdescription: 'Waits until the selector appears in the DOM',\n\t\t\t\tdisplayOptions: { show: { operation: ['waitForSelector'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'CSS Selector',\n\t\t\t\tname: 'selector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['upload'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Binary Property',\n\t\t\t\tname: 'binaryPropertyName',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'data',\n\t\t\t\tdisplayOptions: { show: { operation: ['upload'] } },\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\t\tconst token = creds.token as string;\n\n\t\tconst resolveSid = async (i: number, client: CekiClient) => {\n\t\t\tconst scheduleId = this.getNodeParameter('scheduleId', i) as number;\n\t\t\tif (scheduleId) return scheduleId;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\t\t\tconst list = await client.search({\n\t\t\t\tgeo: geo || undefined,\n\t\t\t\tmax_price_per_min: maxPrice,\n\t\t\t});\n\t\t\tif (!list.length) throw new Error('No browsers found by filters');\n\t\t\treturn list[0].schedule_id;\n\t\t};\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst op = this.getNodeParameter('operation', i) as string;\n\t\t\tconst client = new CekiClient(token);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\ttry {\n\t\t\t\tif (op === 'rent') {\n\t\t\t\t\tconst sid = await resolveSid(i, client);\n\t\t\t\t\tconst mode = this.getNodeParameter('mode', i) as 'main' | 'incognito';\n\t\t\t\t\tbrowser = await client.rent(sid, { mode });\n\t\t\t\t\tout.push({\n\t\t\t\t\t\tjson: { session_id: browser.sessionId, schedule_id: sid, mode },\n\t\t\t\t\t});\n\t\t\t\t\tawait client.disconnect(); // session stays in grace \u2014 the next node resumes it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// remaining operations resume by sessionId\n\t\t\t\tconst sessionId = this.getNodeParameter('sessionId', i) as string;\n\t\t\t\tbrowser = await client.resume(sessionId);\n\t\t\t\tconst sid = browser.sessionId;\n\n\t\t\t\tswitch (op) {\n\t\t\t\t\tcase 'navigate': {\n\t\t\t\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\t\t\t\tawait browser.navigate(url);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, url } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'click': {\n\t\t\t\t\t\tconst x = this.getNodeParameter('x', i) as number;\n\t\t\t\t\t\tconst y = this.getNodeParameter('y', i) as number;\n\t\t\t\t\t\tawait browser.click(x, y);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, clicked: [x, y] } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'type': {\n\t\t\t\t\t\tconst text = this.getNodeParameter('text', i) as string;\n\t\t\t\t\t\tawait browser.type(text);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, typed: text } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'scroll': {\n\t\t\t\t\t\tconst deltaY = this.getNodeParameter('deltaY', i) as number;\n\t\t\t\t\t\tawait browser.scroll(deltaY);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, scrolled: deltaY } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'screenshot': {\n\t\t\t\t\t\tconst format = this.getNodeParameter('format', i) as 'png' | 'base64';\n\t\t\t\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\t\t\t\t\t\tconst shot = await browser.screenshot({ format, fullPage }) as any;\n\t\t\t\t\t\tconst data = format === 'base64' ? shot.data : (shot as Buffer).toString('base64');\n\t\t\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\t\t\tBuffer.from(data, 'base64'),\n\t\t\t\t\t\t\t'screenshot.png',\n\t\t\t\t\t\t\t'image/png',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tout.push({ json: { session_id: sid }, binary: { data: binary } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'snapshot': {\n\t\t\t\t\t\tconst snap = await browser.snapshot();\n\t\t\t\t\t\tout.push({\n\t\t\t\t\t\t\tjson: { session_id: sid, screenshot: snap.screenshot },\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'wait': {\n\t\t\t\t\t\tconst ms = this.getNodeParameter('ms', i) as number;\n\t\t\t\t\t\tawait sleep(ms);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, waited: ms } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'waitForSelector': {\n\t\t\t\t\t\tconst selector = this.getNodeParameter('waitSelector', i) as string;\n\t\t\t\t\t\tconst timeout = this.getNodeParameter('waitTimeout', i) as number;\n\t\t\t\t\t\tconst expr = `!!document.querySelector(${JSON.stringify(selector)})`;\n\t\t\t\t\t\tconst deadline = Date.now() + timeout;\n\t\t\t\t\t\tlet ok = false;\n\t\t\t\t\t\tlet lastErr: unknown = null;\n\t\t\t\t\t\twhile (Date.now() < deadline) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\t\t\t\t\t\t\t\tif (res?.result?.value === true) {\n\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\tlastErr = e;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tawait sleep(500);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!ok) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`waitForSelector(\"${selector}\") timed out after ${timeout}ms${lastErr ? `: ${(lastErr as Error).message}` : ''}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tout.push({ json: { session_id: sid, selector, found: true } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'upload': {\n\t\t\t\t\t\tconst selector = this.getNodeParameter('selector', i) as string;\n\t\t\t\t\t\tconst bpn = this.getNodeParameter('binaryPropertyName', i) as string;\n\t\t\t\t\t\tconst bin = items[i].binary?.[bpn];\n\t\t\t\t\t\tif (!bin) throw new Error(`Binary property \"${bpn}\" not found on input`);\n\t\t\t\t\t\tconst stream = await this.helpers.getBinaryStream(bin.id as string);\n\t\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\t\tfor await (const c of stream) chunks.push(c as Buffer);\n\t\t\t\t\t\tconst buf = Buffer.concat(chunks);\n\t\t\t\t\t\tconst res = await browser.upload(selector, buf);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, uploaded: res } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'close': {\n\t\t\t\t\t\tawait browser.close();\n\t\t\t\t\t\tout.push({ json: { closed: true, session_id: sessionId } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (op === 'close') {\n\t\t\t\t\tawait client.close();\n\t\t\t\t} else {\n\t\t\t\t\tawait client.disconnect(); // session stays alive for the next node\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// trap\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "/**\n * Minimal Ceki contract client \u2014 uses only native fetch (Node 22 global).\n * Zero npm imports (no ws, no axios, no node built-in modules beyond globals).\n *\n * Communicates with Ceki's MCP endpoint via JSON-RPC 2.0 over HTTP POST.\n */\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction cleanArgs<T extends Record<string, unknown>>(o: T): Partial<T> {\n\tconst out = { ...o };\n\tfor (const k of Object.keys(out)) {\n\t\tif ((out as any)[k] === undefined || (out as any)[k] === null) delete (out as any)[k];\n\t}\n\treturn out;\n}\n\nfunction parseBenefitable(value: string | null | undefined): { type: string; value: number } | null {\n\tif (!value) return null;\n\tconst m = /^(agent|user):(\\d+)$/.exec(value);\n\tif (!m) return null;\n\treturn { type: m[1], value: Number(m[2]) };\n}\n\ninterface ParticipantSpec {\n\tparticipable_id: number;\n\ttype: string;\n\trole_id: number;\n}\n\nfunction parseParticipant(value: string | null | undefined, roleId: number): ParticipantSpec | null {\n\tconst b = parseBenefitable(value);\n\tif (!b) return null;\n\treturn { participable_id: b.value, type: b.type, role_id: roleId };\n}\n\nfunction deriveLabel(desc: string | null | undefined): string {\n\tif (!desc) return '';\n\tconst line = desc.split('\\n')[0].trim();\n\treturn line.length > 60 ? line.slice(0, 57) + '...' : line;\n}\n\nconst ROLE_REVIEWER = 5;\nconst ROLE_QA = 6;\n\n// \u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface CreateOptions {\n\tlabel: string;\n\ttype?: number;\n\tstatus?: number;\n\tdescription?: string;\n\tbenefitable?: string;\n\treviewer?: string;\n\tqa?: string;\n}\n\nexport interface ProposeOptions {\n\tstatus?: number;\n\tlabel?: string;\n\tdescription?: string;\n\tbenefitable?: string;\n}\n\nexport interface CommentOptions {\n\tlabel?: string;\n\tdescription?: string;\n}\n\nexport interface ProgressOptions {\n\tstatus?: number;\n\tdesc: string;\n}\n\n// \u2500\u2500 client \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class ContractClient {\n\tprivate _endpoint: string;\n\tprivate _apiBase: string;\n\tprivate _token: string;\n\n\tconstructor(token: string, endpoint?: string, apiBase?: string) {\n\t\tthis._endpoint = (endpoint ?? 'https://api.ceki.me/mcp').replace(/\\/+$/, '');\n\t\tthis._apiBase = (apiBase ?? 'https://api.ceki.me').replace(/\\/+$/, '');\n\t\tthis._token = token;\n\t}\n\n\tprivate _headers(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t\tAuthorization: `Bearer ${this._token}`,\n\t\t};\n\t}\n\n\tprivate async _rpc(method: string, params: Record<string, unknown>): Promise<any> {\n\t\tconst body = JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params });\n\t\tconst resp = await fetch(this._endpoint, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: this._headers(),\n\t\t\tbody,\n\t\t});\n\t\tif (!resp.ok) {\n\t\t\tconst text = await resp.text().catch(() => '');\n\t\t\tthrow new Error(`HTTP ${resp.status}: ${text.slice(0, 400)}`);\n\t\t}\n\t\treturn resp.json();\n\t}\n\n\tprivate async _call(tool: string, args?: Record<string, unknown>): Promise<any> {\n\t\tconst body = await this._rpc('tools/call', { name: tool, arguments: args ?? {} });\n\t\tif (body.error) throw new Error(`${tool} \u2192 ${JSON.stringify(body.error).slice(0, 400)}`);\n\t\tconst result = body.result ?? {};\n\t\tconst content = result.content;\n\t\tif (Array.isArray(content)) {\n\t\t\tconst texts = content.filter((c: any) => c.type === 'text').map((c: any) => String(c.text ?? ''));\n\t\t\tconst joined = texts.join('\\n');\n\t\t\ttry { return JSON.parse(joined); } catch { return joined; }\n\t\t}\n\t\tif (result.structuredContent !== undefined) return result.structuredContent;\n\t\treturn result;\n\t}\n\n\t// \u2500\u2500 domain methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tasync listContracts(): Promise<any> {\n\t\treturn this._call('list-contracts');\n\t}\n\n\tasync members(contractId: number): Promise<any> {\n\t\treturn this._call('contract-members', { contract_id: contractId });\n\t}\n\n\tasync tasks(contractId: number): Promise<any> {\n\t\treturn this._call('contract-tasks', { contract_id: contractId });\n\t}\n\n\tasync myEvents(): Promise<any> {\n\t\treturn this._call('get-my-events');\n\t}\n\n\tasync task(eventId: number): Promise<any> {\n\t\treturn this._call('get-event', { event_id: eventId });\n\t}\n\n\tasync create(contractId: number, opts: CreateOptions): Promise<any> {\n\t\tconst args = cleanArgs({\n\t\t\tcontract_id: contractId,\n\t\t\tlabel: opts.label,\n\t\t\ttype_id: opts.type,\n\t\t\tstatus_id: opts.status,\n\t\t\tdescription: opts.description,\n\t\t\tbenefitable: opts.benefitable ? parseBenefitable(opts.benefitable) : undefined,\n\t\t});\n\t\tconst users: ParticipantSpec[] = [];\n\t\tconst rev = parseParticipant(opts.reviewer, ROLE_REVIEWER);\n\t\tif (rev) users.push(rev);\n\t\tconst qa = parseParticipant(opts.qa, ROLE_QA);\n\t\tif (qa) users.push(qa);\n\t\tif (users.length) (args as any).users = users;\n\t\treturn this._call('create-contract-event', args);\n\t}\n\n\tasync propose(eventId: number, opts: ProposeOptions): Promise<any> {\n\t\treturn this._call('propose-correction', cleanArgs({\n\t\t\tevent_id: eventId,\n\t\t\tstatus_id: opts.status,\n\t\t\tlabel: opts.label,\n\t\t\tdescription: opts.description,\n\t\t\tbenefitable: opts.benefitable ? parseBenefitable(opts.benefitable) : undefined,\n\t\t}));\n\t}\n\n\tasync comment(eventId: number, opts?: CommentOptions): Promise<any> {\n\t\treturn this._call('comment', cleanArgs({\n\t\t\tevent_id: eventId,\n\t\t\tlabel: opts?.label,\n\t\t\tdescription: opts?.description,\n\t\t}));\n\t}\n\n\tasync progress(eventId: number, opts: ProgressOptions): Promise<any> {\n\t\tlet statusResult: any = null;\n\t\tif (opts.status != null) {\n\t\t\tstatusResult = await this.propose(eventId, { status: opts.status });\n\t\t}\n\t\tconst commentResult = await this.comment(eventId, { label: deriveLabel(opts.desc), description: opts.desc });\n\t\treturn { status_correction: statusResult, comment: commentResult };\n\t}\n\n\tasync callHuman(eventId: number, kind: 'input' | 'review' | 'stuck', desc: string): Promise<any> {\n\t\tif (!['input', 'review', 'stuck'].includes(kind)) throw new Error(`kind must be input|review|stuck, got ${kind}`);\n\t\treturn this._call('call-human', { event_id: eventId, kind, desc });\n\t}\n\n\t/** GET /agent/polling. Returns [] on 429. */\n\tasync poll(): Promise<any[]> {\n\t\tconst resp = await fetch(`${this._apiBase}/agent/polling`, {\n\t\t\theaders: { Accept: 'application/json', Authorization: `Bearer ${this._token}` },\n\t\t});\n\t\tif (resp.status === 429) return [];\n\t\tif (!resp.ok) {\n\t\t\tconst text = await resp.text().catch(() => '');\n\t\t\tthrow new Error(`poll HTTP ${resp.status}: ${text.slice(0, 300)}`);\n\t\t}\n\t\tconst body = await resp.json();\n\t\tif (Array.isArray(body)) return body;\n\t\tif (body && typeof body === 'object') {\n\t\t\tfor (const k of ['notifications', 'data', 'items']) {\n\t\t\t\tif (Array.isArray(body[k])) return body[k];\n\t\t\t}\n\t\t}\n\t\treturn [];\n\t}\n}\n", "import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { ContractClient } from '../../lib/contract-client';\n\nconst STATUS_OPTIONS = [\n\t{ name: '100 \u00B7 Backlog', value: 100 },\n\t{ name: '200 \u00B7 Hand (assigned)', value: 200 },\n\t{ name: '222 \u00B7 Hand done', value: 222 },\n\t{ name: '300 \u00B7 QA', value: 300 },\n\t{ name: '350 \u00B7 QA done', value: 350 },\n\t{ name: '499 \u00B7 Reviewer', value: 499 },\n];\n\n/**\n * Ceki Contract \u2014 operation node for the Ceki contract system (tasks/events).\n * Uses native fetch() \u2014 zero external runtime deps.\n */\nexport class CekiContract implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Ceki Contract',\n\t\tname: 'cekiContract',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '={{ \"Contract: \" + $operation }}',\n\t\tdescription: 'Work with Ceki contract tasks: list, create, assign, update status, comment, report progress, escalate to a human, and poll',\n\t\tdefaults: { name: 'Ceki Contract' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'operation',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'myEvents',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'List My Contracts', value: 'listContracts' },\n\t\t\t\t\t{ name: 'List Tasks in Contract', value: 'listTasks' },\n\t\t\t\t\t{ name: 'Get Task', value: 'getTask' },\n\t\t\t\t\t{ name: 'My Assigned Events', value: 'myEvents' },\n\t\t\t\t\t{ name: 'Create Task', value: 'createTask' },\n\t\t\t\t\t{ name: 'Assign Executor', value: 'assign' },\n\t\t\t\t\t{ name: 'Update Status', value: 'setStatus' },\n\t\t\t\t\t{ name: 'Comment', value: 'comment' },\n\t\t\t\t\t{ name: 'Progress Report', value: 'progress' },\n\t\t\t\t\t{ name: 'Call Human', value: 'callHuman' },\n\t\t\t\t\t{ name: 'Poll Notifications', value: 'poll' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t// --- contractId / eventId ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Contract ID',\n\t\t\t\tname: 'contractId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'ceki contract id',\n\t\t\t\tdisplayOptions: { show: { operation: ['listTasks', 'createTask'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Event ID',\n\t\t\t\tname: 'eventId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'Task / event id (KalEvent)',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: { operation: ['getTask', 'assign', 'setStatus', 'comment', 'progress', 'callHuman'] },\n\t\t\t\t},\n\t\t\t},\n\t\t\t// --- createTask fields ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Label',\n\t\t\t\tname: 'label',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'comment'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Executor (benefitable)',\n\t\t\t\tname: 'benefitableType',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'agent',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Agent', value: 'agent' },\n\t\t\t\t\t{ name: 'User (human)', value: 'user' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'assign'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Executor ID',\n\t\t\t\tname: 'benefitableValue',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'Agent ID or user ID of the executor',\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'assign'] } },\n\t\t\t},\n\t\t\t// --- status ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Status',\n\t\t\t\tname: 'status',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: STATUS_OPTIONS,\n\t\t\t\tdefault: 200,\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'setStatus', 'progress'] } },\n\t\t\t},\n\t\t\t// --- progress desc ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Progress Description',\n\t\t\t\tname: 'progressDesc',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Body of the progress comment (does not overwrite the task spec)',\n\t\t\t\tdisplayOptions: { show: { operation: ['progress'] } },\n\t\t\t},\n\t\t\t// --- call human (escalate) ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Call Kind',\n\t\t\t\tname: 'callKind',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'review',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Input (need clarification)', value: 'input' },\n\t\t\t\t\t{ name: 'Review (done, take a look)', value: 'review' },\n\t\t\t\t\t{ name: 'Stuck (blocked)', value: 'stuck' },\n\t\t\t\t],\n\t\t\t\tdescription: 'Type of escalation to a human (the call-human action)',\n\t\t\t\tdisplayOptions: { show: { operation: ['callHuman'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Message',\n\t\t\t\tname: 'callDesc',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'What to tell the human \u2014 context, question, or what was done',\n\t\t\t\tdisplayOptions: { show: { operation: ['callHuman'] } },\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\t\tconst token = creds.token as string;\n\t\tconst client = new ContractClient(token);\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst op = this.getNodeParameter('operation', i) as string;\n\t\t\tlet result: unknown;\n\n\t\t\tswitch (op) {\n\t\t\t\tcase 'listContracts':\n\t\t\t\t\tresult = await client.listContracts();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'listTasks': {\n\t\t\t\t\tconst contractId = this.getNodeParameter('contractId', i) as number;\n\t\t\t\t\tresult = await client.tasks(contractId);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'getTask': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tresult = await client.task(eventId);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'myEvents':\n\t\t\t\t\tresult = await client.myEvents();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'createTask': {\n\t\t\t\t\tconst contractId = this.getNodeParameter('contractId', i) as number;\n\t\t\t\t\tconst label = this.getNodeParameter('label', i) as string;\n\t\t\t\t\tconst description = (this.getNodeParameter('description', i) as string) || '';\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tconst bType = this.getNodeParameter('benefitableType', i) as string;\n\t\t\t\t\tconst bValue = this.getNodeParameter('benefitableValue', i) as number;\n\t\t\t\t\tresult = await client.create(contractId, {\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t\tdescription: description || undefined,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\tbenefitable: bValue ? `${bType}:${bValue}` : undefined,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'assign': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst bType = this.getNodeParameter('benefitableType', i) as string;\n\t\t\t\t\tconst bValue = this.getNodeParameter('benefitableValue', i) as number;\n\t\t\t\t\tif (!bValue) throw new Error('Executor ID is required for Assign');\n\t\t\t\t\tresult = await client.propose(eventId, { benefitable: `${bType}:${bValue}` });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'setStatus': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tresult = await client.propose(eventId, { status });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'comment': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst description = (this.getNodeParameter('description', i) as string) || '';\n\t\t\t\t\tif (!description) throw new Error('Comment text is required');\n\t\t\t\t\tresult = await client.comment(eventId, { description });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tconst desc = this.getNodeParameter('progressDesc', i) as string;\n\t\t\t\t\tresult = await client.progress(eventId, { status, desc });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'callHuman': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst kind = this.getNodeParameter('callKind', i) as 'input' | 'review' | 'stuck';\n\t\t\t\t\tconst desc = this.getNodeParameter('callDesc', i) as string;\n\t\t\t\t\tif (!desc) throw new Error('Message is required for Call Human');\n\t\t\t\t\tresult = await client.callHuman(eventId, kind, desc);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'poll':\n\t\t\t\t\tresult = await client.poll();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown operation: ${op}`);\n\t\t\t}\n\n\t\t\tout.push({ json: { op, result: result as any } });\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';\nimport { CekiClient } from '../../../lib/ceki-client';\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => {\n\tAbortSignal.timeout(ms).addEventListener('abort', () => resolve(), { once: true });\n});\n\nasync function waitForSelector(browser: any, selector: string, timeoutMs: number, intervalMs = 500) {\n\tconst expr = `!!document.querySelector(${JSON.stringify(selector)})`;\n\tconst deadline = Date.now() + timeoutMs;\n\tlet lastErr: unknown = null;\n\twhile (Date.now() < deadline) {\n\t\ttry {\n\t\t\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\t\t\tif (res?.result?.value === true) return true;\n\t\t} catch (e) {\n\t\t\tlastErr = e;\n\t\t}\n\t\tawait sleep(intervalMs);\n\t}\n\tthrow new Error(\n\t\t`waitForSelector(\"${selector}\") timed out after ${timeoutMs}ms${lastErr ? `: ${(lastErr as Error).message}` : ''}`,\n\t);\n}\n\nasync function extractHtml(browser: any, selector: string): Promise<string> {\n\tconst expr =\n\t\tselector.trim() === '' || selector === 'body'\n\t\t\t? `document.body ? document.body.outerHTML : ''`\n\t\t\t: `(function(){ var el = document.querySelector(${JSON.stringify(selector)}); return el ? el.outerHTML : ''; })()`;\n\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\treturn (res?.result?.value as string) ?? '';\n}\n\n/**\n * Recipe: Captcha-protected Scrape.\n * Rent a human browser \u2192 open a URL \u2192 (optional) wait for a selector \u2192\n * snapshot/HTML \u2192 release.\n *\n * The real human fingerprint bypasses anti-bot protection.\n */\nexport class CekiCaptchaScrape implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki: Captcha-protected Scrape',\n\t\tname: 'cekiCaptchaScrape',\n\t\tdescription: 'Rent a human browser, wait, screenshot/HTML, release',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '=rent in {{ $geo }} \u2192 snapshot',\n\t\tdefaults: { name: 'Browser Ceki: Captcha-protected Scrape' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'https://example.com',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Page protected by anti-bot / captcha',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Geo',\n\t\t\t\tname: 'geo',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'RU',\n\t\t\t\tplaceholder: 'RU, EE, US\u2026',\n\t\t\t},\n\t\t\t{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', typeOptions: { numberPrecision: 4 }, default: 0.02 },\n\t\t\t{\n\t\t\t\tdisplayName: 'Wait for Selector',\n\t\t\t\tname: 'waitSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'CSS selector (optional)',\n\t\t\t\tdescription: 'Wait until this selector appears in the DOM',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Wait Timeout (ms)',\n\t\t\t\tname: 'waitTimeout',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 30000,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Extract HTML',\n\t\t\t\tname: 'extractHtml',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'HTML Selector',\n\t\t\t\tname: 'htmlSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'body',\n\t\t\t\tplaceholder: 'CSS selector or \"body\"',\n\t\t\t\tdescription: 'outerHTML of this selector is returned as `html`',\n\t\t\t\tdisplayOptions: { show: { extractHtml: [true] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Full Page Screenshot',\n\t\t\t\tname: 'fullPage',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\t\t\tconst waitSelector = (this.getNodeParameter('waitSelector', i) as string) || '';\n\t\t\tconst waitTimeout = this.getNodeParameter('waitTimeout', i) as number;\n\t\t\tconst extractHtmlFlag = this.getNodeParameter('extractHtml', i) as boolean;\n\t\t\tconst htmlSelector = (this.getNodeParameter('htmlSelector', i) as string) || 'body';\n\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\n\t\t\tconst client = new CekiClient(creds.token as string);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\tlet scheduleId = 0;\n\t\t\ttry {\n\t\t\t\tconst list = await client.search({ geo: geo || undefined, max_price_per_min: maxPrice });\n\t\t\t\tif (!list.length) throw new Error(`No browsers in geo ${geo || '*'}`);\n\t\t\t\tscheduleId = list[0].schedule_id;\n\t\t\t\tbrowser = await client.rent(scheduleId);\n\n\t\t\t\tawait browser.navigate(url);\n\n\t\t\t\tif (waitSelector) {\n\t\t\t\t\tawait waitForSelector(browser, waitSelector, waitTimeout);\n\t\t\t\t}\n\n\t\t\t\tconst shot = await browser.screenshot({ format: 'base64', fullPage }) as any;\n\t\t\t\tconst data = shot.data ?? (shot instanceof Buffer ? shot.toString('base64') : '');\n\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\tBuffer.from(data, 'base64'),\n\t\t\t\t\t'captcha-scrape.png',\n\t\t\t\t\t'image/png',\n\t\t\t\t);\n\n\t\t\t\tconst json: Record<string, unknown> = {\n\t\t\t\t\turl,\n\t\t\t\t\tgeo,\n\t\t\t\t\tschedule_id: scheduleId,\n\t\t\t\t};\n\t\t\t\tif (extractHtmlFlag) {\n\t\t\t\t\tjson.html = await extractHtml(browser, htmlSelector);\n\t\t\t\t}\n\n\t\t\t\tout.push({ json: json as any, binary: { data: binary } });\n\t\t\t} finally {\n\t\t\t\tif (browser) {\n\t\t\t\t\ttry { await browser.close(); } catch { /* ignore */ }\n\t\t\t\t}\n\t\t\t\ttry { await client.close(); } catch { /* ignore */ }\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';\nimport { CekiClient } from '../../../lib/ceki-client';\n\n/**\n * Recipe: Screenshot in Geo.\n * One call \u2014 rent a browser in the requested geo, open a URL, take a screenshot, release.\n */\nexport class CekiScreenshotGeo implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki: Screenshot in Geo',\n\t\tname: 'cekiScreenshotGeo',\n\t\tdescription: 'Rent a browser in a given geo, screenshot a page, release',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '=rent in {{ $geo }} \u2192 screenshot \u2192 release',\n\t\tdefaults: { name: 'Browser Ceki: Screenshot in Geo' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'https://ifconfig.me',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{ displayName: 'Geo', name: 'geo', type: 'string', default: 'RU', placeholder: 'RU, EE, US\u2026' },\n\t\t\t{ displayName: 'Full page', name: 'fullPage', type: 'boolean', default: false },\n\t\t\t{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', default: 0.02 },\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\n\t\t\tconst client = new CekiClient(creds.token as string);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\ttry {\n\t\t\t\tconst list = await client.search({ geo, max_price_per_min: maxPrice });\n\t\t\t\tif (!list.length) throw new Error(`No browsers in geo ${geo}`);\n\t\t\t\tbrowser = await client.rent(list[0].schedule_id);\n\t\t\t\tawait browser.navigate(url);\n\t\t\t\tconst shot = await browser.screenshot({ format: 'base64', fullPage }) as any;\n\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\tBuffer.from(shot.data, 'base64'),\n\t\t\t\t\t'screenshot.png',\n\t\t\t\t\t'image/png',\n\t\t\t\t);\n\t\t\t\tout.push({\n\t\t\t\t\tjson: { url, geo, schedule_id: list[0].schedule_id },\n\t\t\t\t\tbinary: { data: binary },\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tif (browser) { try { await browser.close(); } catch {} }\n\t\t\t\ttry { await client.close(); } catch {}\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type { ICredentialType, INodeProperties } from 'n8n-workflow';\n\n/**\n * Ceki agent token (ag_...). Authorizes every Ceki node.\n * Get it from the Ceki panel \u2192 agent profile \u2192 API key.\n */\nexport class CekiApi implements ICredentialType {\n\tname = 'cekiApi';\n\tdisplayName = 'Ceki API';\n\tdocumentationUrl = 'https://browser.ceki.me/docs#api-key';\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'token',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'Agent token (ag_...). [Get your API key \u2192](https://browser.ceki.me/docs#api-key)',\n\t\t\trequired: true,\n\t\t},\n\t];\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { BrowserCeki } from './nodes/BrowserCeki/BrowserCeki.node';\nimport { CekiContract } from './nodes/CekiContract/CekiContract.node';\nimport { CekiCaptchaScrape } from './nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node';\nimport { CekiScreenshotGeo } from './nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node';\nimport { CekiApi } from './credentials/CekiApi.credentials';\n\nexport const nodes = [\n\tBrowserCeki,\n\tCekiContract,\n\tCekiCaptchaScrape,\n\tCekiScreenshotGeo,\n];\n\nexport const credentials = [\n\tCekiApi,\n];\n", "/**\n * Minimal Ceki browser client \u2014 uses only native WebSocket + fetch (Node 22 globals).\n * Zero npm imports (no ws, no mime-types, no node built-in modules).\n *\n * Timeout management: uses AbortSignal.timeout() instead of restricted\n * setTimeout/clearTimeout globals to satisfy the n8n community-nodes\n * package scanner (no-restricted-globals rule).\n */\n\n// \u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface BrowserOption {\n\tschedule_id: number;\n\tgeo?: string;\n\tprice_per_min: number;\n\tonline: boolean;\n\trating?: number | null;\n}\n\nexport interface Match {\n\tsession_id: string;\n\tschedule_id: number;\n\tevent_id?: string | null;\n\tchat_topic_id?: string | null;\n\tprovider_user_id?: number | null;\n\tbrowser_info?: Record<string, unknown>;\n}\n\nexport interface RentOptions {\n\tmode?: 'main' | 'incognito';\n}\n\nexport interface ScreenshotOptions {\n\tformat?: 'png' | 'base64';\n\tfullPage?: boolean;\n}\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction jsonParse(raw: string): unknown {\n\ttry { return JSON.parse(raw); } catch { return null; }\n}\n\n// \u2500\u2500 Client \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class CekiClient {\n\tprivate _ws: WebSocket | null = null;\n\tprivate _connected = false;\n\tprivate _pendingRents = new Map<string, {\n\t\tresolve: (m: Match) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _pendingResumes = new Map<string, {\n\t\tresolve: (m: Match) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _pendingCdp = new Map<number, {\n\t\tresolve: (v: unknown) => void;\n\t\treject: (e: Error) => void;\n\t}>();\n\tprivate _cdpCounter = 1;\n\t_activeSessions = new Map<string, CekiBrowser>();\n\tprivate _connectReject: ((e: Error) => void) | null = null;\n\tprivate _closed = false;\n\n\tconstructor(\n\t\tprivate _token: string,\n\t\tprivate _relayUrl = 'wss://browser.ceki.me/ws/agent',\n\t\tprivate _apiUrl = 'https://api.ceki.me',\n\t) {}\n\n\t/** Connect to the relay WebSocket. */\n\tasync connect(): Promise<void> {\n\t\tif (this._connected) return;\n\t\tconst protocols = [`bearer.${this._token}`];\n\t\tthis._ws = new WebSocket(this._relayUrl, protocols);\n\t\tthis._ws.onopen = () => {\n\t\t\tthis._connected = true;\n\t\t};\n\t\tthis._ws.onmessage = (ev: MessageEvent) => {\n\t\t\tthis._handleMessage(ev.data);\n\t\t};\n\t\tthis._ws.onclose = (ev: CloseEvent) => {\n\t\t\tthis._connected = false;\n\t\t\tif ((ev.code === 4401 || ev.code === 4403) && this._connectReject) {\n\t\t\t\tthis._connectReject(new Error(`Auth failed: ${ev.reason || String(ev.code)}`));\n\t\t\t\tthis._connectReject = null;\n\t\t\t}\n\t\t};\n\t\tthis._ws.onerror = () => {\n\t\t\tif (!this._connected && this._connectReject) {\n\t\t\t\tthis._connectReject(new Error('WebSocket connection failed'));\n\t\t\t\tthis._connectReject = null;\n\t\t\t}\n\t\t};\n\t\tif (this._ws.readyState === WebSocket.CONNECTING) {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tif (!this._ws) { reject(new Error('No WebSocket')); return; }\n\t\t\t\tthis._connectReject = reject;\n\t\t\t\tthis._ws!.onopen = () => {\n\t\t\t\t\tthis._connected = true;\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t_sendRaw(msg: Record<string, unknown>): void {\n\t\tif (!this._ws || this._ws.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new Error('WebSocket not connected');\n\t\t}\n\t\tthis._ws.send(JSON.stringify(msg));\n\t}\n\n\t/** Search for available browser providers (HTTP GET). */\n\tasync search(filters?: Record<string, unknown>, limit?: number): Promise<BrowserOption[]> {\n\t\tconst params = new URLSearchParams();\n\t\tif (limit != null) params.set('limit', String(limit));\n\t\tif (filters) {\n\t\t\tfor (const [k, v] of Object.entries(filters)) {\n\t\t\t\tif (v != null) params.set(k, String(v));\n\t\t\t}\n\t\t}\n\t\tconst resp = await fetch(`${this._apiUrl}/api/browsers/search?${params}`, {\n\t\t\theaders: { Authorization: `Bearer ${this._token}` },\n\t\t});\n\t\tif (!resp.ok) throw new Error(`Search failed: ${resp.status}`);\n\t\tconst body = (await resp.json()) as Record<string, unknown>;\n\t\tconst data = (body.data ?? body) as unknown[];\n\t\treturn Array.isArray(data) ? data as BrowserOption[] : [];\n\t}\n\n\t/** Rent a browser by schedule_id. */\n\tasync rent(scheduleId: number, opts?: RentOptions): Promise<CekiBrowser> {\n\t\tconst msg: Record<string, unknown> = { type: 'rent', browser_id: scheduleId };\n\t\tif (opts?.mode) msg.mode = opts.mode;\n\t\tthis._sendRaw(msg);\n\t\treturn this._awaitRent(`rent:${scheduleId}`, scheduleId, 90000);\n\t}\n\n\t/** Resume an existing session. */\n\tasync resume(sessionId: string): Promise<CekiBrowser> {\n\t\tthis._sendRaw({ type: 'resume', session_id: sessionId });\n\t\treturn this._awaitResume(sessionId);\n\t}\n\n\t/** Close the WS connection \u2014 session stays alive in grace. */\n\tdisconnect(): void {\n\t\tthis._closed = true;\n\t\tthis._activeSessions.clear();\n\t\tthis._pendingRents.clear();\n\t\tthis._pendingResumes.clear();\n\t\tthis._closeWs();\n\t}\n\n\t/** Close everything. */\n\tclose(): void {\n\t\tthis.disconnect();\n\t}\n\n\t// \u2500\u2500 private \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate _awaitRent(key: string, scheduleId: number, timeoutMs: number): Promise<CekiBrowser> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(timeoutMs);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingRents.delete(key);\n\t\t\t\treject(new Error('Rent timed out'));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingRents.set(key, {\n\t\t\t\tresolve: (match: Match) => {\n\t\t\t\t\tconst browser = new CekiBrowser(this, match);\n\t\t\t\t\tthis._activeSessions.set(browser.sessionId, browser);\n\t\t\t\t\tresolve(browser);\n\t\t\t\t},\n\t\t\t\treject: (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _awaitResume(sessionId: string): Promise<CekiBrowser> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(10000);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingResumes.delete(sessionId);\n\t\t\t\treject(new Error('Resume timed out'));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingResumes.set(sessionId, {\n\t\t\t\tresolve: (match: Match) => {\n\t\t\t\t\tconst browser = new CekiBrowser(this, match);\n\t\t\t\t\tthis._activeSessions.set(browser.sessionId, browser);\n\t\t\t\t\tresolve(browser);\n\t\t\t\t},\n\t\t\t\treject: (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _closeWs(): void {\n\t\tif (this._ws) {\n\t\t\ttry { this._ws.onopen = null; this._ws.onmessage = null; this._ws.onclose = null; this._ws.onerror = null; this._ws.close(); } catch { /* ignore */ }\n\t\t\tthis._ws = null;\n\t\t}\n\t}\n\n\tprivate _handleMessage(data: unknown): void {\n\t\tconst msg = jsonParse(String(data)) as Record<string, unknown> | null;\n\t\tif (!msg || typeof msg !== 'object') return;\n\t\tconst type = String(msg.type ?? '');\n\t\tconst sid = msg.session_id ? String(msg.session_id) : null;\n\n\t\tswitch (type) {\n\t\t\tcase 'pong':\n\t\t\tcase 'rent_pending':\n\t\t\t\tbreak;\n\t\t\tcase 'match':\n\t\t\t\tthis._onMatch(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'rent.error':\n\t\t\t\tthis._onRentError(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'resume_ok':\n\t\t\t\tthis._onResumeOk(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'resume_failed':\n\t\t\t\tthis._onResumeFailed(msg);\n\t\t\t\tbreak;\n\t\t\tcase 'cdp_response':\n\t\t\t\tif (sid) this._onCdpResponse(sid, msg);\n\t\t\t\tbreak;\n\t\t\tcase 'session.ended':\n\t\t\t\tif (sid) {\n\t\t\t\t\tthis._activeSessions.delete(sid);\n\t\t\t\t\tconst b = this._activeSessions.get(sid);\n\t\t\t\t\tif (b) (b as any)._ended = String(msg.reason ?? 'ended');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate _onMatch(msg: Record<string, unknown>): void {\n\t\tconst scheduleId = Number(msg.schedule_id ?? 0);\n\t\tconst eventId = msg.event_id ? String(msg.event_id) : null;\n\t\tlet pending = this._pendingRents.get(`event:${eventId}`);\n\t\tif (!pending) pending = this._pendingRents.get(`rent:${scheduleId}`);\n\t\tif (pending) {\n\t\t\tthis._pendingRents.delete(`event:${eventId}`);\n\t\t\tthis._pendingRents.delete(`rent:${scheduleId}`);\n\t\t\tpending.resolve({\n\t\t\t\tsession_id: String(msg.session_id ?? ''),\n\t\t\t\tschedule_id: scheduleId,\n\t\t\t\tevent_id: eventId,\n\t\t\t\tchat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,\n\t\t\t\tprovider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,\n\t\t\t\tbrowser_info: (msg.browser_info ?? {}) as Record<string, unknown>,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate _onRentError(msg: Record<string, unknown>): void {\n\t\tconst code = String(msg.code ?? '');\n\t\tconst message = String(msg.message ?? '');\n\t\tfor (const [key, pending] of this._pendingRents) {\n\t\t\tthis._pendingRents.delete(key);\n\t\t\tpending.reject(new Error(message || `Rent error: ${code}`));\n\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate _onResumeOk(msg: Record<string, unknown>): void {\n\t\tconst sessionId = String(msg.session_id ?? '');\n\t\tconst pending = this._pendingResumes.get(sessionId);\n\t\tif (!pending) return;\n\t\tthis._pendingResumes.delete(sessionId);\n\t\tpending.resolve({\n\t\t\tsession_id: sessionId,\n\t\t\tschedule_id: Number(msg.schedule_id ?? 0),\n\t\t\tevent_id: msg.event_id ? String(msg.event_id) : null,\n\t\t\tchat_topic_id: msg.chat_topic_id ? String(msg.chat_topic_id) : null,\n\t\t\tprovider_user_id: msg.provider_user_id != null ? Number(msg.provider_user_id) : null,\n\t\t\tbrowser_info: (msg.browser_info ?? {}) as Record<string, unknown>,\n\t\t});\n\t}\n\n\tprivate _onResumeFailed(msg: Record<string, unknown>): void {\n\t\tconst sessionId = String(msg.session_id ?? '');\n\t\tconst pending = this._pendingResumes.get(sessionId);\n\t\tif (!pending) return;\n\t\tthis._pendingResumes.delete(sessionId);\n\t\tpending.reject(new Error(String(msg.reason ?? 'Resume failed')));\n\t}\n\n\tprivate _onCdpResponse(sessionId: string, msg: Record<string, unknown>): void {\n\t\tconst browser = this._activeSessions.get(sessionId);\n\t\tif (!browser) return;\n\t\tconst id = Number(msg.id ?? 0);\n\t\tconst pending = this._pendingCdp.get(id);\n\t\tif (!pending) return;\n\t\tthis._pendingCdp.delete(id);\n\t\tif (msg.error) {\n\t\t\tpending.reject(new Error(String((msg.error as Record<string, unknown>).message ?? 'CDP error')));\n\t\t} else {\n\t\t\tpending.resolve(msg.result);\n\t\t}\n\t}\n}\n\n// \u2500\u2500 Browser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class CekiBrowser {\n\treadonly sessionId: string;\n\treadonly scheduleId: number;\n\treadonly chatTopicId: string | null;\n\treadonly browserInfo: Record<string, unknown>;\n\treadonly providerUserId: number | null;\n\n\tprivate _client: CekiClient;\n\tprivate _cdpId = 1;\n\t_pendingCdp = new Map<number, { resolve: (v: unknown) => void; reject: (e: Error) => void }>();\n\n\tconstructor(client: CekiClient, match: Match) {\n\t\tthis._client = client;\n\t\tthis.sessionId = match.session_id;\n\t\tthis.scheduleId = match.schedule_id;\n\t\tthis.chatTopicId = match.chat_topic_id ?? null;\n\t\tthis.browserInfo = match.browser_info ?? {};\n\t\tthis.providerUserId = match.provider_user_id ?? null;\n\t}\n\n\t/** Send a CDP command. Uses AbortSignal.timeout() (no restricted setTimeout global). */\n\tasync send(method: string, params?: Record<string, unknown>, timeoutMs = 30000): Promise<unknown> {\n\t\tconst id = this._cdpId++;\n\t\tconst msg = { type: 'cdp', session_id: this.sessionId, id, method, params: params ?? {} };\n\t\tthis._client._sendRaw(msg);\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeoutSignal = AbortSignal.timeout(timeoutMs);\n\t\t\ttimeoutSignal.addEventListener('abort', () => {\n\t\t\t\tthis._pendingCdp.delete(id);\n\t\t\t\treject(new Error(`CDP ${method} timed out after ${timeoutMs}ms`));\n\t\t\t}, { once: true });\n\t\t\tthis._pendingCdp.set(id, {\n\t\t\t\tresolve: (v) => { resolve(v); },\n\t\t\t\treject: (e) => { reject(e); },\n\t\t\t});\n\t\t});\n\t}\n\n\tasync navigate(url: string, timeoutMs?: number): Promise<void> {\n\t\tawait this.send('Page.navigate', { url }, timeoutMs);\n\t}\n\n\tasync click(x: number, y: number): Promise<void> {\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mousePressed', x, y, button: 'left', clickCount: 1 });\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mouseReleased', x, y, button: 'left', clickCount: 1 });\n\t}\n\n\tasync type(text: string): Promise<void> {\n\t\tawait this.send('Ceki.typeText', { text });\n\t}\n\n\tasync scroll(deltaY: number): Promise<void> {\n\t\tawait this.send('Input.dispatchMouseEvent', { type: 'mouseWheel', x: 0, y: 0, deltaX: 0, deltaY });\n\t}\n\n\tasync screenshot(opts?: ScreenshotOptions): Promise<{ data: string } | Buffer> {\n\t\tconst format = opts?.format ?? 'base64';\n\t\tconst fullPage = opts?.fullPage ?? false;\n\t\tlet clip: Record<string, number> | undefined;\n\t\tif (fullPage) {\n\t\t\tconst metrics = await this.send('Page.getLayoutMetrics') as Record<string, unknown> | null;\n\t\t\tconst contentSize = metrics?.contentSize as Record<string, number> | undefined;\n\t\t\tif (contentSize) {\n\t\t\t\tclip = { x: 0, y: 0, width: Number(contentSize.width ?? 1920), height: Math.min(Number(contentSize.height ?? 1080), 16384), scale: 1 };\n\t\t\t}\n\t\t}\n\t\tconst result = await this.send('Page.captureScreenshot', { format: 'png', ...(clip ? { clip } : {}) }) as Record<string, unknown> | null;\n\t\tconst data = String(result?.data ?? '');\n\t\tif (format === 'png') {\n\t\t\treturn Buffer.from(data, 'base64');\n\t\t}\n\t\treturn { data };\n\t}\n\n\tasync snapshot(): Promise<{ screenshot: string; ts: Date }> {\n\t\tconst ssResult = await this.screenshot({ format: 'base64' }) as { data: string };\n\t\treturn { screenshot: ssResult.data, ts: new Date() };\n\t}\n\n\tasync upload(selector: string, buf: Buffer, filename = 'file'): Promise<Record<string, unknown>> {\n\t\tconst b64 = buf.toString('base64');\n\t\tconst size = buf.length;\n\t\tconst mime = 'application/octet-stream';\n\t\tconst expression = `(function(){\n\t\t\tvar input = document.querySelector(${JSON.stringify(selector)});\n\t\t\tif (!input) return JSON.stringify({ok:false,error:'Element not found'});\n\t\t\tvar b = atob(${JSON.stringify(b64)});\n\t\t\tvar u = new Uint8Array(b.length);\n\t\t\tfor (var i = 0; i < b.length; i++) u[i] = b.charCodeAt(i);\n\t\t\tvar f = new File([u], ${JSON.stringify(filename)}, {type: ${JSON.stringify(mime)}});\n\t\t\tvar dt = new DataTransfer(); dt.items.add(f);\n\t\t\tinput.files = dt.files;\n\t\t\tinput.dispatchEvent(new Event('change',{bubbles:true}));\n\t\t\treturn JSON.stringify({ok:true,filename:${JSON.stringify(filename)},size:${size}});\n\t\t})()`;\n\t\tconst result = await this.send('Runtime.evaluate', { expression, returnByValue: true }) as Record<string, unknown> | null;\n\t\ttry {\n\t\t\tawait this.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'Escape', code: 'Escape', windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });\n\t\t\tawait this.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'Escape', code: 'Escape', windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });\n\t\t} catch { /* ignore */ }\n\t\tconst resultObj = result?.result as Record<string, unknown> | undefined;\n\t\tif (resultObj?.value) return JSON.parse(String(resultObj.value)) as Record<string, unknown>;\n\t\treturn { ok: true, filename, size };\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.send('Ceki.close', {}).catch(() => {});\n\t\tthis._client._activeSessions.delete(this.sessionId);\n\t}\n}\n", "import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { CekiClient } from '../../lib/ceki-client';\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => {\n\tAbortSignal.timeout(ms).addEventListener('abort', () => resolve(), { once: true });\n});\n\n/**\n * Browser Ceki \u2014 one node, many operations.\n * Uses native WebSocket (not the ws library) \u2014 zero external runtime deps.\n */\nexport class BrowserCeki implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki',\n\t\tname: 'browserCeki',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '={{ \"Ceki: \" + $operation }}',\n\t\tdescription: 'Rent a real human browser and control it: rent, navigate, click, type, screenshot, solve captchas, and more',\n\t\tdefaults: { name: 'Browser Ceki' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'operation',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'rent',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Rent', value: 'rent' },\n\t\t\t\t\t{ name: 'Navigate', value: 'navigate' },\n\t\t\t\t\t{ name: 'Click', value: 'click' },\n\t\t\t\t\t{ name: 'Type', value: 'type' },\n\t\t\t\t\t{ name: 'Scroll', value: 'scroll' },\n\t\t\t\t\t{ name: 'Screenshot', value: 'screenshot' },\n\t\t\t\t\t{ name: 'Snapshot', value: 'snapshot' },\n\t\t\t\t\t{ name: 'Wait', value: 'wait' },\n\t\t\t\t\t{ name: 'Wait for Selector', value: 'waitForSelector' },\n\t\t\t\t\t{ name: 'Upload', value: 'upload' },\n\t\t\t\t\t{ name: 'Close', value: 'close' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t// === Rent: rental parameters ===\n\t\t\t{\n\t\t\t\tdisplayName: 'Schedule ID',\n\t\t\t\tname: 'scheduleId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: '0 \u2014 search by the filters below',\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Geo',\n\t\t\t\tname: 'geo',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'RU, EE, US\u2026',\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Max $/min',\n\t\t\t\tname: 'maxPrice',\n\t\t\t\ttype: 'number',\n\t\t\t\ttypeOptions: { numberPrecision: 4 },\n\t\t\t\tdefault: 0.02,\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Min rating',\n\t\t\t\tname: 'minRating',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Profile mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'main',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'main', value: 'main' },\n\t\t\t\t\t{ name: 'incognito', value: 'incognito' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['rent'] } },\n\t\t\t},\n\t\t\t// === Operations: session_id ===\n\t\t\t{\n\t\t\t\tdisplayName: 'Session ID',\n\t\t\t\tname: 'sessionId',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '={{ $json.session_id }}',\n\t\t\t\tdescription: 'From the Rent operation',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\toperation: ['navigate', 'click', 'type', 'scroll', 'screenshot', 'snapshot', 'wait', 'waitForSelector', 'upload', 'close'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['navigate'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'X',\n\t\t\t\tname: 'x',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['click'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Y',\n\t\t\t\tname: 'y',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdisplayOptions: { show: { operation: ['click'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: { show: { operation: ['type'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Delta Y',\n\t\t\t\tname: 'deltaY',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: -300,\n\t\t\t\tdisplayOptions: { show: { operation: ['scroll'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Format',\n\t\t\t\tname: 'format',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'png',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'PNG (binary)', value: 'png' },\n\t\t\t\t\t{ name: 'Base64', value: 'base64' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['screenshot'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Full page',\n\t\t\t\tname: 'fullPage',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdisplayOptions: { show: { operation: ['screenshot'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Milliseconds',\n\t\t\t\tname: 'ms',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 1000,\n\t\t\t\ttypeOptions: { minValue: 0 },\n\t\t\t\tdescription: 'Fixed delay on the active session',\n\t\t\t\tdisplayOptions: { show: { operation: ['wait'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'CSS Selector',\n\t\t\t\tname: 'waitSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tplaceholder: 'e.g. .results, #content, table tr',\n\t\t\t\tdisplayOptions: { show: { operation: ['waitForSelector'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Timeout (ms)',\n\t\t\t\tname: 'waitTimeout',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 30000,\n\t\t\t\tdescription: 'Waits until the selector appears in the DOM',\n\t\t\t\tdisplayOptions: { show: { operation: ['waitForSelector'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'CSS Selector',\n\t\t\t\tname: 'selector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['upload'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Binary Property',\n\t\t\t\tname: 'binaryPropertyName',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'data',\n\t\t\t\tdisplayOptions: { show: { operation: ['upload'] } },\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\t\tconst token = creds.token as string;\n\n\t\tconst resolveSid = async (i: number, client: CekiClient) => {\n\t\t\tconst scheduleId = this.getNodeParameter('scheduleId', i) as number;\n\t\t\tif (scheduleId) return scheduleId;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\t\t\tconst list = await client.search({\n\t\t\t\tgeo: geo || undefined,\n\t\t\t\tmax_price_per_min: maxPrice,\n\t\t\t});\n\t\t\tif (!list.length) throw new Error('No browsers found by filters');\n\t\t\treturn list[0].schedule_id;\n\t\t};\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst op = this.getNodeParameter('operation', i) as string;\n\t\t\tconst client = new CekiClient(token);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\ttry {\n\t\t\t\tif (op === 'rent') {\n\t\t\t\t\tconst sid = await resolveSid(i, client);\n\t\t\t\t\tconst mode = this.getNodeParameter('mode', i) as 'main' | 'incognito';\n\t\t\t\t\tbrowser = await client.rent(sid, { mode });\n\t\t\t\t\tout.push({\n\t\t\t\t\t\tjson: { session_id: browser.sessionId, schedule_id: sid, mode },\n\t\t\t\t\t});\n\t\t\t\t\tawait client.disconnect(); // session stays in grace \u2014 the next node resumes it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// remaining operations resume by sessionId\n\t\t\t\tconst sessionId = this.getNodeParameter('sessionId', i) as string;\n\t\t\t\tbrowser = await client.resume(sessionId);\n\t\t\t\tconst sid = browser.sessionId;\n\n\t\t\t\tswitch (op) {\n\t\t\t\t\tcase 'navigate': {\n\t\t\t\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\t\t\t\tawait browser.navigate(url);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, url } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'click': {\n\t\t\t\t\t\tconst x = this.getNodeParameter('x', i) as number;\n\t\t\t\t\t\tconst y = this.getNodeParameter('y', i) as number;\n\t\t\t\t\t\tawait browser.click(x, y);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, clicked: [x, y] } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'type': {\n\t\t\t\t\t\tconst text = this.getNodeParameter('text', i) as string;\n\t\t\t\t\t\tawait browser.type(text);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, typed: text } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'scroll': {\n\t\t\t\t\t\tconst deltaY = this.getNodeParameter('deltaY', i) as number;\n\t\t\t\t\t\tawait browser.scroll(deltaY);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, scrolled: deltaY } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'screenshot': {\n\t\t\t\t\t\tconst format = this.getNodeParameter('format', i) as 'png' | 'base64';\n\t\t\t\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\t\t\t\t\t\tconst shot = await browser.screenshot({ format, fullPage }) as any;\n\t\t\t\t\t\tconst data = format === 'base64' ? shot.data : (shot as Buffer).toString('base64');\n\t\t\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\t\t\tBuffer.from(data, 'base64'),\n\t\t\t\t\t\t\t'screenshot.png',\n\t\t\t\t\t\t\t'image/png',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tout.push({ json: { session_id: sid }, binary: { data: binary } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'snapshot': {\n\t\t\t\t\t\tconst snap = await browser.snapshot();\n\t\t\t\t\t\tout.push({\n\t\t\t\t\t\t\tjson: { session_id: sid, screenshot: snap.screenshot },\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'wait': {\n\t\t\t\t\t\tconst ms = this.getNodeParameter('ms', i) as number;\n\t\t\t\t\t\tawait sleep(ms);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, waited: ms } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'waitForSelector': {\n\t\t\t\t\t\tconst selector = this.getNodeParameter('waitSelector', i) as string;\n\t\t\t\t\t\tconst timeout = this.getNodeParameter('waitTimeout', i) as number;\n\t\t\t\t\t\tconst expr = `!!document.querySelector(${JSON.stringify(selector)})`;\n\t\t\t\t\t\tconst deadline = Date.now() + timeout;\n\t\t\t\t\t\tlet ok = false;\n\t\t\t\t\t\tlet lastErr: unknown = null;\n\t\t\t\t\t\twhile (Date.now() < deadline) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\t\t\t\t\t\t\t\tif (res?.result?.value === true) {\n\t\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\tlastErr = e;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tawait sleep(500);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!ok) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`waitForSelector(\"${selector}\") timed out after ${timeout}ms${lastErr ? `: ${(lastErr as Error).message}` : ''}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tout.push({ json: { session_id: sid, selector, found: true } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'upload': {\n\t\t\t\t\t\tconst selector = this.getNodeParameter('selector', i) as string;\n\t\t\t\t\t\tconst bpn = this.getNodeParameter('binaryPropertyName', i) as string;\n\t\t\t\t\t\tconst bin = items[i].binary?.[bpn];\n\t\t\t\t\t\tif (!bin) throw new Error(`Binary property \"${bpn}\" not found on input`);\n\t\t\t\t\t\tconst stream = await this.helpers.getBinaryStream(bin.id as string);\n\t\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\t\tfor await (const c of stream) chunks.push(c as Buffer);\n\t\t\t\t\t\tconst buf = Buffer.concat(chunks);\n\t\t\t\t\t\tconst res = await browser.upload(selector, buf);\n\t\t\t\t\t\tout.push({ json: { session_id: sid, uploaded: res } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'close': {\n\t\t\t\t\t\tawait browser.close();\n\t\t\t\t\t\tout.push({ json: { closed: true, session_id: sessionId } });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (op === 'close') {\n\t\t\t\t\tawait client.close();\n\t\t\t\t} else {\n\t\t\t\t\tawait client.disconnect(); // session stays alive for the next node\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// trap\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "/**\n * Minimal Ceki contract client \u2014 uses only native fetch (Node 22 global).\n * Zero npm imports (no ws, no axios, no node built-in modules beyond globals).\n *\n * Communicates with Ceki's MCP endpoint via JSON-RPC 2.0 over HTTP POST.\n */\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction cleanArgs<T extends Record<string, unknown>>(o: T): Partial<T> {\n\tconst out = { ...o };\n\tfor (const k of Object.keys(out)) {\n\t\tif ((out as any)[k] === undefined || (out as any)[k] === null) delete (out as any)[k];\n\t}\n\treturn out;\n}\n\nfunction parseBenefitable(value: string | null | undefined): { type: string; value: number } | null {\n\tif (!value) return null;\n\tconst m = /^(agent|user):(\\d+)$/.exec(value);\n\tif (!m) return null;\n\treturn { type: m[1], value: Number(m[2]) };\n}\n\ninterface ParticipantSpec {\n\tparticipable_id: number;\n\ttype: string;\n\trole_id: number;\n}\n\nfunction parseParticipant(value: string | null | undefined, roleId: number): ParticipantSpec | null {\n\tconst b = parseBenefitable(value);\n\tif (!b) return null;\n\treturn { participable_id: b.value, type: b.type, role_id: roleId };\n}\n\nfunction deriveLabel(desc: string | null | undefined): string {\n\tif (!desc) return '';\n\tconst line = desc.split('\\n')[0].trim();\n\treturn line.length > 60 ? line.slice(0, 57) + '...' : line;\n}\n\nconst ROLE_REVIEWER = 5;\nconst ROLE_QA = 6;\n\n// \u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface CreateOptions {\n\tlabel: string;\n\ttype?: number;\n\tstatus?: number;\n\tdescription?: string;\n\tbenefitable?: string;\n\treviewer?: string;\n\tqa?: string;\n}\n\nexport interface ProposeOptions {\n\tstatus?: number;\n\tlabel?: string;\n\tdescription?: string;\n\tbenefitable?: string;\n}\n\nexport interface CommentOptions {\n\tlabel?: string;\n\tdescription?: string;\n}\n\nexport interface ProgressOptions {\n\tstatus?: number;\n\tdesc: string;\n}\n\n// \u2500\u2500 client \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class ContractClient {\n\tprivate _endpoint: string;\n\tprivate _apiBase: string;\n\tprivate _token: string;\n\n\tconstructor(token: string, endpoint?: string, apiBase?: string) {\n\t\tthis._endpoint = (endpoint ?? 'https://api.ceki.me/mcp').replace(/\\/+$/, '');\n\t\tthis._apiBase = (apiBase ?? 'https://api.ceki.me').replace(/\\/+$/, '');\n\t\tthis._token = token;\n\t}\n\n\tprivate _headers(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t\tAuthorization: `Bearer ${this._token}`,\n\t\t};\n\t}\n\n\tprivate async _rpc(method: string, params: Record<string, unknown>): Promise<any> {\n\t\tconst body = JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params });\n\t\tconst resp = await fetch(this._endpoint, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: this._headers(),\n\t\t\tbody,\n\t\t});\n\t\tif (!resp.ok) {\n\t\t\tconst text = await resp.text().catch(() => '');\n\t\t\tthrow new Error(`HTTP ${resp.status}: ${text.slice(0, 400)}`);\n\t\t}\n\t\treturn resp.json();\n\t}\n\n\tprivate async _call(tool: string, args?: Record<string, unknown>): Promise<any> {\n\t\tconst body = await this._rpc('tools/call', { name: tool, arguments: args ?? {} });\n\t\tif (body.error) throw new Error(`${tool} \u2192 ${JSON.stringify(body.error).slice(0, 400)}`);\n\t\tconst result = body.result ?? {};\n\t\tconst content = result.content;\n\t\tif (Array.isArray(content)) {\n\t\t\tconst texts = content.filter((c: any) => c.type === 'text').map((c: any) => String(c.text ?? ''));\n\t\t\tconst joined = texts.join('\\n');\n\t\t\ttry { return JSON.parse(joined); } catch { return joined; }\n\t\t}\n\t\tif (result.structuredContent !== undefined) return result.structuredContent;\n\t\treturn result;\n\t}\n\n\t// \u2500\u2500 domain methods \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tasync listContracts(): Promise<any> {\n\t\treturn this._call('list-contracts');\n\t}\n\n\tasync members(contractId: number): Promise<any> {\n\t\treturn this._call('contract-members', { contract_id: contractId });\n\t}\n\n\tasync tasks(contractId: number): Promise<any> {\n\t\treturn this._call('contract-tasks', { contract_id: contractId });\n\t}\n\n\tasync myEvents(): Promise<any> {\n\t\treturn this._call('get-my-events');\n\t}\n\n\tasync task(eventId: number): Promise<any> {\n\t\treturn this._call('get-event', { event_id: eventId });\n\t}\n\n\tasync create(contractId: number, opts: CreateOptions): Promise<any> {\n\t\tconst args = cleanArgs({\n\t\t\tcontract_id: contractId,\n\t\t\tlabel: opts.label,\n\t\t\ttype_id: opts.type,\n\t\t\tstatus_id: opts.status,\n\t\t\tdescription: opts.description,\n\t\t\tbenefitable: opts.benefitable ? parseBenefitable(opts.benefitable) : undefined,\n\t\t});\n\t\tconst users: ParticipantSpec[] = [];\n\t\tconst rev = parseParticipant(opts.reviewer, ROLE_REVIEWER);\n\t\tif (rev) users.push(rev);\n\t\tconst qa = parseParticipant(opts.qa, ROLE_QA);\n\t\tif (qa) users.push(qa);\n\t\tif (users.length) (args as any).users = users;\n\t\treturn this._call('create-contract-event', args);\n\t}\n\n\tasync propose(eventId: number, opts: ProposeOptions): Promise<any> {\n\t\treturn this._call('propose-correction', cleanArgs({\n\t\t\tevent_id: eventId,\n\t\t\tstatus_id: opts.status,\n\t\t\tlabel: opts.label,\n\t\t\tdescription: opts.description,\n\t\t\tbenefitable: opts.benefitable ? parseBenefitable(opts.benefitable) : undefined,\n\t\t}));\n\t}\n\n\tasync comment(eventId: number, opts?: CommentOptions): Promise<any> {\n\t\treturn this._call('comment', cleanArgs({\n\t\t\tevent_id: eventId,\n\t\t\tlabel: opts?.label,\n\t\t\tdescription: opts?.description,\n\t\t}));\n\t}\n\n\tasync progress(eventId: number, opts: ProgressOptions): Promise<any> {\n\t\tlet statusResult: any = null;\n\t\tif (opts.status != null) {\n\t\t\tstatusResult = await this.propose(eventId, { status: opts.status });\n\t\t}\n\t\tconst commentResult = await this.comment(eventId, { label: deriveLabel(opts.desc), description: opts.desc });\n\t\treturn { status_correction: statusResult, comment: commentResult };\n\t}\n\n\tasync callHuman(eventId: number, kind: 'input' | 'review' | 'stuck', desc: string): Promise<any> {\n\t\tif (!['input', 'review', 'stuck'].includes(kind)) throw new Error(`kind must be input|review|stuck, got ${kind}`);\n\t\treturn this._call('call-human', { event_id: eventId, kind, desc });\n\t}\n\n\t/** GET /agent/polling. Returns [] on 429. */\n\tasync poll(): Promise<any[]> {\n\t\tconst resp = await fetch(`${this._apiBase}/agent/polling`, {\n\t\t\theaders: { Accept: 'application/json', Authorization: `Bearer ${this._token}` },\n\t\t});\n\t\tif (resp.status === 429) return [];\n\t\tif (!resp.ok) {\n\t\t\tconst text = await resp.text().catch(() => '');\n\t\t\tthrow new Error(`poll HTTP ${resp.status}: ${text.slice(0, 300)}`);\n\t\t}\n\t\tconst body = await resp.json();\n\t\tif (Array.isArray(body)) return body;\n\t\tif (body && typeof body === 'object') {\n\t\t\tfor (const k of ['notifications', 'data', 'items']) {\n\t\t\t\tif (Array.isArray(body[k])) return body[k];\n\t\t\t}\n\t\t}\n\t\treturn [];\n\t}\n}\n", "import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { ContractClient } from '../../lib/contract-client';\n\nconst STATUS_OPTIONS = [\n\t{ name: '100 \u00B7 Backlog', value: 100 },\n\t{ name: '200 \u00B7 Hand (assigned)', value: 200 },\n\t{ name: '222 \u00B7 Hand done', value: 222 },\n\t{ name: '300 \u00B7 QA', value: 300 },\n\t{ name: '350 \u00B7 QA done', value: 350 },\n\t{ name: '499 \u00B7 Reviewer', value: 499 },\n];\n\n/**\n * Ceki Contract \u2014 operation node for the Ceki contract system (tasks/events).\n * Uses native fetch() \u2014 zero external runtime deps.\n */\nexport class CekiContract implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Ceki Contract',\n\t\tname: 'cekiContract',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '={{ \"Contract: \" + $operation }}',\n\t\tdescription: 'Work with Ceki contract tasks: list, create, assign, update status, comment, report progress, escalate to a human, and poll',\n\t\tdefaults: { name: 'Ceki Contract' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'operation',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'myEvents',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'List My Contracts', value: 'listContracts' },\n\t\t\t\t\t{ name: 'List Tasks in Contract', value: 'listTasks' },\n\t\t\t\t\t{ name: 'Get Task', value: 'getTask' },\n\t\t\t\t\t{ name: 'My Assigned Events', value: 'myEvents' },\n\t\t\t\t\t{ name: 'Create Task', value: 'createTask' },\n\t\t\t\t\t{ name: 'Assign Executor', value: 'assign' },\n\t\t\t\t\t{ name: 'Update Status', value: 'setStatus' },\n\t\t\t\t\t{ name: 'Comment', value: 'comment' },\n\t\t\t\t\t{ name: 'Progress Report', value: 'progress' },\n\t\t\t\t\t{ name: 'Call Human', value: 'callHuman' },\n\t\t\t\t\t{ name: 'Poll Notifications', value: 'poll' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t// --- contractId / eventId ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Contract ID',\n\t\t\t\tname: 'contractId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'ceki contract id',\n\t\t\t\tdisplayOptions: { show: { operation: ['listTasks', 'createTask'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Event ID',\n\t\t\t\tname: 'eventId',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'Task / event id (KalEvent)',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: { operation: ['getTask', 'assign', 'setStatus', 'comment', 'progress', 'callHuman'] },\n\t\t\t\t},\n\t\t\t},\n\t\t\t// --- createTask fields ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Label',\n\t\t\t\tname: 'label',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'comment'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Executor (benefitable)',\n\t\t\t\tname: 'benefitableType',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'agent',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Agent', value: 'agent' },\n\t\t\t\t\t{ name: 'User (human)', value: 'user' },\n\t\t\t\t],\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'assign'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Executor ID',\n\t\t\t\tname: 'benefitableValue',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 0,\n\t\t\t\tdescription: 'Agent ID or user ID of the executor',\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'assign'] } },\n\t\t\t},\n\t\t\t// --- status ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Status',\n\t\t\t\tname: 'status',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: STATUS_OPTIONS,\n\t\t\t\tdefault: 200,\n\t\t\t\tdisplayOptions: { show: { operation: ['createTask', 'setStatus', 'progress'] } },\n\t\t\t},\n\t\t\t// --- progress desc ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Progress Description',\n\t\t\t\tname: 'progressDesc',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Body of the progress comment (does not overwrite the task spec)',\n\t\t\t\tdisplayOptions: { show: { operation: ['progress'] } },\n\t\t\t},\n\t\t\t// --- call human (escalate) ---\n\t\t\t{\n\t\t\t\tdisplayName: 'Call Kind',\n\t\t\t\tname: 'callKind',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'review',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Input (need clarification)', value: 'input' },\n\t\t\t\t\t{ name: 'Review (done, take a look)', value: 'review' },\n\t\t\t\t\t{ name: 'Stuck (blocked)', value: 'stuck' },\n\t\t\t\t],\n\t\t\t\tdescription: 'Type of escalation to a human (the call-human action)',\n\t\t\t\tdisplayOptions: { show: { operation: ['callHuman'] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Message',\n\t\t\t\tname: 'callDesc',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: { rows: 4 },\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'What to tell the human \u2014 context, question, or what was done',\n\t\t\t\tdisplayOptions: { show: { operation: ['callHuman'] } },\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\t\tconst token = creds.token as string;\n\t\tconst client = new ContractClient(token);\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst op = this.getNodeParameter('operation', i) as string;\n\t\t\tlet result: unknown;\n\n\t\t\tswitch (op) {\n\t\t\t\tcase 'listContracts':\n\t\t\t\t\tresult = await client.listContracts();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'listTasks': {\n\t\t\t\t\tconst contractId = this.getNodeParameter('contractId', i) as number;\n\t\t\t\t\tresult = await client.tasks(contractId);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'getTask': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tresult = await client.task(eventId);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'myEvents':\n\t\t\t\t\tresult = await client.myEvents();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'createTask': {\n\t\t\t\t\tconst contractId = this.getNodeParameter('contractId', i) as number;\n\t\t\t\t\tconst label = this.getNodeParameter('label', i) as string;\n\t\t\t\t\tconst description = (this.getNodeParameter('description', i) as string) || '';\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tconst bType = this.getNodeParameter('benefitableType', i) as string;\n\t\t\t\t\tconst bValue = this.getNodeParameter('benefitableValue', i) as number;\n\t\t\t\t\tresult = await client.create(contractId, {\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t\tdescription: description || undefined,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\tbenefitable: bValue ? `${bType}:${bValue}` : undefined,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'assign': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst bType = this.getNodeParameter('benefitableType', i) as string;\n\t\t\t\t\tconst bValue = this.getNodeParameter('benefitableValue', i) as number;\n\t\t\t\t\tif (!bValue) throw new Error('Executor ID is required for Assign');\n\t\t\t\t\tresult = await client.propose(eventId, { benefitable: `${bType}:${bValue}` });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'setStatus': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tresult = await client.propose(eventId, { status });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'comment': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst description = (this.getNodeParameter('description', i) as string) || '';\n\t\t\t\t\tif (!description) throw new Error('Comment text is required');\n\t\t\t\t\tresult = await client.comment(eventId, { description });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'progress': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst status = this.getNodeParameter('status', i) as number;\n\t\t\t\t\tconst desc = this.getNodeParameter('progressDesc', i) as string;\n\t\t\t\t\tresult = await client.progress(eventId, { status, desc });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'callHuman': {\n\t\t\t\t\tconst eventId = this.getNodeParameter('eventId', i) as number;\n\t\t\t\t\tconst kind = this.getNodeParameter('callKind', i) as 'input' | 'review' | 'stuck';\n\t\t\t\t\tconst desc = this.getNodeParameter('callDesc', i) as string;\n\t\t\t\t\tif (!desc) throw new Error('Message is required for Call Human');\n\t\t\t\t\tresult = await client.callHuman(eventId, kind, desc);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'poll':\n\t\t\t\t\tresult = await client.poll();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown operation: ${op}`);\n\t\t\t}\n\n\t\t\tout.push({ json: { op, result: result as any } });\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';\nimport { CekiClient } from '../../../lib/ceki-client';\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => {\n\tAbortSignal.timeout(ms).addEventListener('abort', () => resolve(), { once: true });\n});\n\nasync function waitForSelector(browser: any, selector: string, timeoutMs: number, intervalMs = 500) {\n\tconst expr = `!!document.querySelector(${JSON.stringify(selector)})`;\n\tconst deadline = Date.now() + timeoutMs;\n\tlet lastErr: unknown = null;\n\twhile (Date.now() < deadline) {\n\t\ttry {\n\t\t\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\t\t\tif (res?.result?.value === true) return true;\n\t\t} catch (e) {\n\t\t\tlastErr = e;\n\t\t}\n\t\tawait sleep(intervalMs);\n\t}\n\tthrow new Error(\n\t\t`waitForSelector(\"${selector}\") timed out after ${timeoutMs}ms${lastErr ? `: ${(lastErr as Error).message}` : ''}`,\n\t);\n}\n\nasync function extractHtml(browser: any, selector: string): Promise<string> {\n\tconst expr =\n\t\tselector.trim() === '' || selector === 'body'\n\t\t\t? `document.body ? document.body.outerHTML : ''`\n\t\t\t: `(function(){ var el = document.querySelector(${JSON.stringify(selector)}); return el ? el.outerHTML : ''; })()`;\n\tconst res = await browser.send('Runtime.evaluate', { expression: expr, returnByValue: true }) as any;\n\treturn (res?.result?.value as string) ?? '';\n}\n\n/**\n * Recipe: Captcha-protected Scrape.\n * Rent a human browser \u2192 open a URL \u2192 (optional) wait for a selector \u2192\n * snapshot/HTML \u2192 release.\n *\n * The real human fingerprint bypasses anti-bot protection.\n */\nexport class CekiCaptchaScrape implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki: Captcha-protected Scrape',\n\t\tname: 'cekiCaptchaScrape',\n\t\tdescription: 'Rent a human browser, wait, screenshot/HTML, release',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '=rent in {{ $geo }} \u2192 snapshot',\n\t\tdefaults: { name: 'Browser Ceki: Captcha-protected Scrape' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'https://example.com',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'Page protected by anti-bot / captcha',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Geo',\n\t\t\t\tname: 'geo',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'RU',\n\t\t\t\tplaceholder: 'RU, EE, US\u2026',\n\t\t\t},\n\t\t\t{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', typeOptions: { numberPrecision: 4 }, default: 0.02 },\n\t\t\t{\n\t\t\t\tdisplayName: 'Wait for Selector',\n\t\t\t\tname: 'waitSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'CSS selector (optional)',\n\t\t\t\tdescription: 'Wait until this selector appears in the DOM',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Wait Timeout (ms)',\n\t\t\t\tname: 'waitTimeout',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 30000,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Extract HTML',\n\t\t\t\tname: 'extractHtml',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'HTML Selector',\n\t\t\t\tname: 'htmlSelector',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'body',\n\t\t\t\tplaceholder: 'CSS selector or \"body\"',\n\t\t\t\tdescription: 'outerHTML of this selector is returned as `html`',\n\t\t\t\tdisplayOptions: { show: { extractHtml: [true] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Full Page Screenshot',\n\t\t\t\tname: 'fullPage',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\t\t\tconst waitSelector = (this.getNodeParameter('waitSelector', i) as string) || '';\n\t\t\tconst waitTimeout = this.getNodeParameter('waitTimeout', i) as number;\n\t\t\tconst extractHtmlFlag = this.getNodeParameter('extractHtml', i) as boolean;\n\t\t\tconst htmlSelector = (this.getNodeParameter('htmlSelector', i) as string) || 'body';\n\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\n\t\t\tconst client = new CekiClient(creds.token as string);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\tlet scheduleId = 0;\n\t\t\ttry {\n\t\t\t\tconst list = await client.search({ geo: geo || undefined, max_price_per_min: maxPrice });\n\t\t\t\tif (!list.length) throw new Error(`No browsers in geo ${geo || '*'}`);\n\t\t\t\tscheduleId = list[0].schedule_id;\n\t\t\t\tbrowser = await client.rent(scheduleId);\n\n\t\t\t\tawait browser.navigate(url);\n\n\t\t\t\tif (waitSelector) {\n\t\t\t\t\tawait waitForSelector(browser, waitSelector, waitTimeout);\n\t\t\t\t}\n\n\t\t\t\tconst shot = await browser.screenshot({ format: 'base64', fullPage }) as any;\n\t\t\t\tconst data = shot.data ?? (shot instanceof Buffer ? shot.toString('base64') : '');\n\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\tBuffer.from(data, 'base64'),\n\t\t\t\t\t'captcha-scrape.png',\n\t\t\t\t\t'image/png',\n\t\t\t\t);\n\n\t\t\t\tconst json: Record<string, unknown> = {\n\t\t\t\t\turl,\n\t\t\t\t\tgeo,\n\t\t\t\t\tschedule_id: scheduleId,\n\t\t\t\t};\n\t\t\t\tif (extractHtmlFlag) {\n\t\t\t\t\tjson.html = await extractHtml(browser, htmlSelector);\n\t\t\t\t}\n\n\t\t\t\tout.push({ json: json as any, binary: { data: binary } });\n\t\t\t} finally {\n\t\t\t\tif (browser) {\n\t\t\t\t\ttry { await browser.close(); } catch { /* ignore */ }\n\t\t\t\t}\n\t\t\t\ttry { await client.close(); } catch { /* ignore */ }\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';\nimport { CekiClient } from '../../../lib/ceki-client';\n\n/**\n * Recipe: Screenshot in Geo.\n * One call \u2014 rent a browser in the requested geo, open a URL, take a screenshot, release.\n */\nexport class CekiScreenshotGeo implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Browser Ceki: Screenshot in Geo',\n\t\tname: 'cekiScreenshotGeo',\n\t\tdescription: 'Rent a browser in a given geo, screenshot a page, release',\n\t\ticon: 'file:ceki.png',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tsubtitle: '=rent in {{ $geo }} \u2192 screenshot \u2192 release',\n\t\tdefaults: { name: 'Browser Ceki: Screenshot in Geo' },\n\t\tinputs: ['main'],\n\t\toutputs: ['main'],\n\t\tcredentials: [{ name: 'cekiApi', required: true }],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'https://ifconfig.me',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{ displayName: 'Geo', name: 'geo', type: 'string', default: 'RU', placeholder: 'RU, EE, US\u2026' },\n\t\t\t{ displayName: 'Full page', name: 'fullPage', type: 'boolean', default: false },\n\t\t\t{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', default: 0.02 },\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst out: INodeExecutionData[] = [];\n\t\tconst creds = await this.getCredentials('cekiApi');\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst url = this.getNodeParameter('url', i) as string;\n\t\t\tconst geo = this.getNodeParameter('geo', i) as string;\n\t\t\tconst fullPage = this.getNodeParameter('fullPage', i) as boolean;\n\t\t\tconst maxPrice = this.getNodeParameter('maxPrice', i) as number;\n\n\t\t\tconst client = new CekiClient(creds.token as string);\n\t\t\tawait client.connect();\n\t\t\tlet browser: any;\n\t\t\ttry {\n\t\t\t\tconst list = await client.search({ geo, max_price_per_min: maxPrice });\n\t\t\t\tif (!list.length) throw new Error(`No browsers in geo ${geo}`);\n\t\t\t\tbrowser = await client.rent(list[0].schedule_id);\n\t\t\t\tawait browser.navigate(url);\n\t\t\t\tconst shot = await browser.screenshot({ format: 'base64', fullPage }) as any;\n\t\t\t\tconst binary = await this.helpers.prepareBinaryData(\n\t\t\t\t\tBuffer.from(shot.data, 'base64'),\n\t\t\t\t\t'screenshot.png',\n\t\t\t\t\t'image/png',\n\t\t\t\t);\n\t\t\t\tout.push({\n\t\t\t\t\tjson: { url, geo, schedule_id: list[0].schedule_id },\n\t\t\t\t\tbinary: { data: binary },\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tif (browser) { try { await browser.close(); } catch {} }\n\t\t\t\ttry { await client.close(); } catch {}\n\t\t\t}\n\t\t}\n\t\treturn [out];\n\t}\n}\n", "import type {\n\tIAuthenticateGeneric,\n\tICredentialTestRequest,\n\tICredentialType,\n\tINodeProperties,\n} from 'n8n-workflow';\n\n/**\n * Ceki agent token (ag_...). Authorizes every Ceki node.\n * Get it from the Ceki panel \u2192 agent profile \u2192 API key.\n */\nexport class CekiApi implements ICredentialType {\n\tname = 'cekiApi';\n\tdisplayName = 'Ceki API';\n\tdocumentationUrl = 'https://browser.ceki.me/docs#api-key';\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'token',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'Agent token (ag_...). [Get your API key \u2192](https://browser.ceki.me/docs#api-key)',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{$credentials?.token}}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tbaseURL: 'https://api.ceki.me',\n\t\t\turl: '/api/browsers/search',\n\t\t\tmethod: 'GET',\n\t\t},\n\t};\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["sid", "sleep"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceki/n8n-nodes-ceki",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Rent real human browsers in n8n — anti-bot scraping, human-solved captchas, geo-targeting, and contract-based hiring of agents and humans. Powered by Ceki.",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",