arise-browser 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +247 -0
  3. package/deploy/neko/CONTEXT.md +37 -0
  4. package/deploy/neko/arise-browser.service +13 -0
  5. package/deploy/neko/neko.yaml +12 -0
  6. package/deploy/neko/openbox.xml +763 -0
  7. package/deploy/neko/policies.json +28 -0
  8. package/deploy/neko/pulseaudio.pa +16 -0
  9. package/deploy/neko/setup.sh +308 -0
  10. package/deploy/neko/xorg.conf +118 -0
  11. package/dist/bin/arise-browser.d.ts +26 -0
  12. package/dist/bin/arise-browser.d.ts.map +1 -0
  13. package/dist/bin/arise-browser.js +224 -0
  14. package/dist/bin/arise-browser.js.map +1 -0
  15. package/dist/src/browser/action-executor.d.ts +98 -0
  16. package/dist/src/browser/action-executor.d.ts.map +1 -0
  17. package/dist/src/browser/action-executor.js +2726 -0
  18. package/dist/src/browser/action-executor.js.map +1 -0
  19. package/dist/src/browser/behavior-recorder.d.ts +61 -0
  20. package/dist/src/browser/behavior-recorder.d.ts.map +1 -0
  21. package/dist/src/browser/behavior-recorder.js +442 -0
  22. package/dist/src/browser/behavior-recorder.js.map +1 -0
  23. package/dist/src/browser/browser-session.d.ts +202 -0
  24. package/dist/src/browser/browser-session.d.ts.map +1 -0
  25. package/dist/src/browser/browser-session.js +1647 -0
  26. package/dist/src/browser/browser-session.js.map +1 -0
  27. package/dist/src/browser/config.d.ts +43 -0
  28. package/dist/src/browser/config.d.ts.map +1 -0
  29. package/dist/src/browser/config.js +59 -0
  30. package/dist/src/browser/config.js.map +1 -0
  31. package/dist/src/browser/page-snapshot.d.ts +38 -0
  32. package/dist/src/browser/page-snapshot.d.ts.map +1 -0
  33. package/dist/src/browser/page-snapshot.js +241 -0
  34. package/dist/src/browser/page-snapshot.js.map +1 -0
  35. package/dist/src/browser/scripts/behavior_tracker.js +424 -0
  36. package/dist/src/browser/scripts/unified_analyzer.js +1576 -0
  37. package/dist/src/index.d.ts +15 -0
  38. package/dist/src/index.d.ts.map +1 -0
  39. package/dist/src/index.js +15 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/lock.d.ts +11 -0
  42. package/dist/src/lock.d.ts.map +1 -0
  43. package/dist/src/lock.js +47 -0
  44. package/dist/src/lock.js.map +1 -0
  45. package/dist/src/logger.d.ts +17 -0
  46. package/dist/src/logger.d.ts.map +1 -0
  47. package/dist/src/logger.js +29 -0
  48. package/dist/src/logger.js.map +1 -0
  49. package/dist/src/server/middleware/auth.d.ts +6 -0
  50. package/dist/src/server/middleware/auth.d.ts.map +1 -0
  51. package/dist/src/server/middleware/auth.js +24 -0
  52. package/dist/src/server/middleware/auth.js.map +1 -0
  53. package/dist/src/server/route-utils.d.ts +15 -0
  54. package/dist/src/server/route-utils.d.ts.map +1 -0
  55. package/dist/src/server/route-utils.js +33 -0
  56. package/dist/src/server/route-utils.js.map +1 -0
  57. package/dist/src/server/routes/action.d.ts +5 -0
  58. package/dist/src/server/routes/action.d.ts.map +1 -0
  59. package/dist/src/server/routes/action.js +69 -0
  60. package/dist/src/server/routes/action.js.map +1 -0
  61. package/dist/src/server/routes/actions.d.ts +3 -0
  62. package/dist/src/server/routes/actions.d.ts.map +1 -0
  63. package/dist/src/server/routes/actions.js +53 -0
  64. package/dist/src/server/routes/actions.js.map +1 -0
  65. package/dist/src/server/routes/cookies.d.ts +3 -0
  66. package/dist/src/server/routes/cookies.d.ts.map +1 -0
  67. package/dist/src/server/routes/cookies.js +27 -0
  68. package/dist/src/server/routes/cookies.js.map +1 -0
  69. package/dist/src/server/routes/download.d.ts +3 -0
  70. package/dist/src/server/routes/download.d.ts.map +1 -0
  71. package/dist/src/server/routes/download.js +35 -0
  72. package/dist/src/server/routes/download.js.map +1 -0
  73. package/dist/src/server/routes/evaluate.d.ts +3 -0
  74. package/dist/src/server/routes/evaluate.d.ts.map +1 -0
  75. package/dist/src/server/routes/evaluate.js +27 -0
  76. package/dist/src/server/routes/evaluate.js.map +1 -0
  77. package/dist/src/server/routes/health.d.ts +3 -0
  78. package/dist/src/server/routes/health.d.ts.map +1 -0
  79. package/dist/src/server/routes/health.js +11 -0
  80. package/dist/src/server/routes/health.js.map +1 -0
  81. package/dist/src/server/routes/navigate.d.ts +3 -0
  82. package/dist/src/server/routes/navigate.d.ts.map +1 -0
  83. package/dist/src/server/routes/navigate.js +36 -0
  84. package/dist/src/server/routes/navigate.js.map +1 -0
  85. package/dist/src/server/routes/page-model.d.ts +3 -0
  86. package/dist/src/server/routes/page-model.d.ts.map +1 -0
  87. package/dist/src/server/routes/page-model.js +22 -0
  88. package/dist/src/server/routes/page-model.js.map +1 -0
  89. package/dist/src/server/routes/pdf.d.ts +3 -0
  90. package/dist/src/server/routes/pdf.d.ts.map +1 -0
  91. package/dist/src/server/routes/pdf.js +20 -0
  92. package/dist/src/server/routes/pdf.js.map +1 -0
  93. package/dist/src/server/routes/recording.d.ts +5 -0
  94. package/dist/src/server/routes/recording.d.ts.map +1 -0
  95. package/dist/src/server/routes/recording.js +217 -0
  96. package/dist/src/server/routes/recording.js.map +1 -0
  97. package/dist/src/server/routes/screenshot.d.ts +3 -0
  98. package/dist/src/server/routes/screenshot.d.ts.map +1 -0
  99. package/dist/src/server/routes/screenshot.js +32 -0
  100. package/dist/src/server/routes/screenshot.js.map +1 -0
  101. package/dist/src/server/routes/snapshot.d.ts +3 -0
  102. package/dist/src/server/routes/snapshot.d.ts.map +1 -0
  103. package/dist/src/server/routes/snapshot.js +454 -0
  104. package/dist/src/server/routes/snapshot.js.map +1 -0
  105. package/dist/src/server/routes/tab-lock.d.ts +3 -0
  106. package/dist/src/server/routes/tab-lock.d.ts.map +1 -0
  107. package/dist/src/server/routes/tab-lock.js +30 -0
  108. package/dist/src/server/routes/tab-lock.js.map +1 -0
  109. package/dist/src/server/routes/tab.d.ts +3 -0
  110. package/dist/src/server/routes/tab.d.ts.map +1 -0
  111. package/dist/src/server/routes/tab.js +47 -0
  112. package/dist/src/server/routes/tab.js.map +1 -0
  113. package/dist/src/server/routes/tabs.d.ts +3 -0
  114. package/dist/src/server/routes/tabs.d.ts.map +1 -0
  115. package/dist/src/server/routes/tabs.js +13 -0
  116. package/dist/src/server/routes/tabs.js.map +1 -0
  117. package/dist/src/server/routes/text.d.ts +3 -0
  118. package/dist/src/server/routes/text.d.ts.map +1 -0
  119. package/dist/src/server/routes/text.js +20 -0
  120. package/dist/src/server/routes/text.js.map +1 -0
  121. package/dist/src/server/routes/upload.d.ts +3 -0
  122. package/dist/src/server/routes/upload.d.ts.map +1 -0
  123. package/dist/src/server/routes/upload.js +38 -0
  124. package/dist/src/server/routes/upload.js.map +1 -0
  125. package/dist/src/server/server.d.ts +7 -0
  126. package/dist/src/server/server.d.ts.map +1 -0
  127. package/dist/src/server/server.js +69 -0
  128. package/dist/src/server/server.js.map +1 -0
  129. package/dist/src/types/index.d.ts +125 -0
  130. package/dist/src/types/index.d.ts.map +1 -0
  131. package/dist/src/types/index.js +5 -0
  132. package/dist/src/types/index.js.map +1 -0
  133. package/dist/src/virtual-display/manager.d.ts +37 -0
  134. package/dist/src/virtual-display/manager.d.ts.map +1 -0
  135. package/dist/src/virtual-display/manager.js +229 -0
  136. package/dist/src/virtual-display/manager.js.map +1 -0
  137. package/dist/src/virtual-display/process-runner.d.ts +43 -0
  138. package/dist/src/virtual-display/process-runner.d.ts.map +1 -0
  139. package/dist/src/virtual-display/process-runner.js +174 -0
  140. package/dist/src/virtual-display/process-runner.js.map +1 -0
  141. package/dist/tsconfig.tsbuildinfo +1 -0
  142. package/package.json +57 -0
  143. package/plugin/openclaw.plugin.json +148 -0
  144. package/skill/arise-browser/SKILL.md +275 -0
  145. package/skill/arise-browser/TRUST.md +42 -0
  146. package/skill/arise-browser/references/api.md +198 -0
  147. package/src/browser/scripts/behavior_tracker.js +424 -0
  148. package/src/browser/scripts/unified_analyzer.js +1576 -0
@@ -0,0 +1,442 @@
1
+ /**
2
+ * BehaviorRecorder — Records user behavior using ref-based element identification.
3
+ *
4
+ * Key concepts:
5
+ * - CDP session per tab for JS -> Node binding
6
+ * - Injects behavior_tracker.js via Page.addScriptToEvaluateOnNewDocument
7
+ * - Handles Runtime.bindingCalled for click/type/scroll/navigate events
8
+ * - Network response monitoring for dataload detection
9
+ * - Navigation deduplication (2s window)
10
+ * - Auto-hooks new tab creation
11
+ */
12
+ import { readFileSync } from "node:fs";
13
+ import { createHash, randomUUID } from "node:crypto";
14
+ import { resolve, dirname } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+ import { createLogger } from "../logger.js";
17
+ const MAX_OPERATIONS = 10_000;
18
+ const logger = createLogger("behavior-recorder");
19
+ // ===== Tracker script cache =====
20
+ let _trackerJsCache = null;
21
+ function getTrackerScript() {
22
+ if (_trackerJsCache !== null)
23
+ return _trackerJsCache;
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ const candidates = [
27
+ // Development: src/browser/ -> src/browser/scripts/
28
+ resolve(__dirname, "scripts/behavior_tracker.js"),
29
+ // Compiled: dist/src/browser/ -> project root/src/browser/scripts/
30
+ resolve(__dirname, "../../../src/browser/scripts/behavior_tracker.js"),
31
+ ];
32
+ for (const candidate of candidates) {
33
+ try {
34
+ _trackerJsCache = readFileSync(candidate, "utf-8");
35
+ logger.info({ path: candidate }, "Loaded behavior_tracker.js");
36
+ return _trackerJsCache;
37
+ }
38
+ catch {
39
+ // try next
40
+ }
41
+ }
42
+ // Minimal fallback
43
+ logger.warn("Using minimal fallback tracker script");
44
+ _trackerJsCache = `
45
+ (function() {
46
+ if (window._behaviorTrackerInitialized) return;
47
+ window._behaviorTrackerInitialized = true;
48
+ console.log("Behavior Tracker (fallback) initialized");
49
+ function report(type, data) {
50
+ if (window.reportUserBehavior) {
51
+ const payload = { type, timestamp: new Date().toISOString(), url: location.href, ...data };
52
+ window.reportUserBehavior(JSON.stringify(payload));
53
+ }
54
+ }
55
+ document.addEventListener('click', e => {
56
+ const ref = e.target.getAttribute('aria-ref');
57
+ if (ref) report('click', { ref, text: e.target.textContent?.slice(0, 100) });
58
+ }, true);
59
+ })();
60
+ `;
61
+ return _trackerJsCache;
62
+ }
63
+ // ===== BehaviorRecorder class =====
64
+ export class BehaviorRecorder {
65
+ sessionId;
66
+ _isRecording = false;
67
+ _enableSnapshotCapture;
68
+ operations = [];
69
+ snapshots = {};
70
+ _monitoredTabs = new Set();
71
+ _tabPages = new Map();
72
+ _cdpSessions = new Map();
73
+ _lastNavUrl = null;
74
+ _lastNavTime = null;
75
+ _navDedupMs = 2000;
76
+ _browserSession = null;
77
+ _operationCallback = null;
78
+ _recentDataloadUrls = new Set();
79
+ _dataloadCleanupTimer = null;
80
+ _lastScrollTime = null;
81
+ _dataloadWindowMs = 3000;
82
+ _responseListeners = new Map();
83
+ _unsubscribePageRegistered = null;
84
+ constructor(enableSnapshotCapture = true) {
85
+ this.sessionId = `recording_${randomUUID()}`;
86
+ this._enableSnapshotCapture = enableSnapshotCapture;
87
+ }
88
+ setOperationCallback(callback) {
89
+ this._operationCallback = callback;
90
+ }
91
+ isRecording() {
92
+ return this._isRecording;
93
+ }
94
+ getOperations() {
95
+ return [...this.operations];
96
+ }
97
+ getOperationsCount() {
98
+ return this.operations.length;
99
+ }
100
+ // ===== Start / Stop =====
101
+ async startRecording(browserSession) {
102
+ if (this._isRecording) {
103
+ logger.warn("Recording already in progress");
104
+ return;
105
+ }
106
+ this._browserSession = browserSession;
107
+ this._isRecording = true;
108
+ this.operations = [];
109
+ this.snapshots = {};
110
+ this._monitoredTabs.clear();
111
+ this._tabPages.clear();
112
+ this._unsubscribePageRegistered?.();
113
+ this._unsubscribePageRegistered = null;
114
+ logger.info({ sessionId: this.sessionId }, "Starting behavior recording");
115
+ if (browserSession.onPageRegistered) {
116
+ this._unsubscribePageRegistered = browserSession.onPageRegistered((tabId, page) => this._setupForTab(tabId, page));
117
+ }
118
+ await this._setupAllTabs();
119
+ this._dataloadCleanupTimer = setInterval(() => {
120
+ this._recentDataloadUrls.clear();
121
+ }, 10_000);
122
+ }
123
+ async stopRecording() {
124
+ if (!this._isRecording) {
125
+ logger.warn("No recording in progress");
126
+ return { session_id: this.sessionId, operations: [], operations_count: 0, snapshots: {} };
127
+ }
128
+ this._isRecording = false;
129
+ logger.info({ operationCount: this.operations.length }, "Stopping recording");
130
+ const result = {
131
+ session_id: this.sessionId,
132
+ operations: [...this.operations],
133
+ operations_count: this.operations.length,
134
+ snapshots: { ...this.snapshots },
135
+ };
136
+ for (const [tabId, cdpSession] of this._cdpSessions) {
137
+ try {
138
+ await cdpSession.detach();
139
+ }
140
+ catch (e) {
141
+ logger.debug({ tabId, err: e }, "Error detaching CDP session");
142
+ }
143
+ }
144
+ for (const [tabId, page] of this._tabPages) {
145
+ try {
146
+ const listener = this._responseListeners.get(tabId);
147
+ if (listener) {
148
+ page.off("response", listener);
149
+ }
150
+ }
151
+ catch {
152
+ // page may be closed
153
+ }
154
+ }
155
+ this._responseListeners.clear();
156
+ this._monitoredTabs.clear();
157
+ this._tabPages.clear();
158
+ this._cdpSessions.clear();
159
+ this._browserSession = null;
160
+ this._recentDataloadUrls.clear();
161
+ this._unsubscribePageRegistered?.();
162
+ this._unsubscribePageRegistered = null;
163
+ if (this._dataloadCleanupTimer) {
164
+ clearInterval(this._dataloadCleanupTimer);
165
+ this._dataloadCleanupTimer = null;
166
+ }
167
+ return result;
168
+ }
169
+ // ===== Tab Setup =====
170
+ async _setupAllTabs() {
171
+ if (!this._browserSession)
172
+ return;
173
+ for (const [tabId, page] of this._browserSession.pages) {
174
+ if (!this._monitoredTabs.has(tabId)) {
175
+ await this._setupForTab(tabId, page);
176
+ }
177
+ }
178
+ }
179
+ async _setupForTab(tabId, page) {
180
+ if (this._monitoredTabs.has(tabId))
181
+ return;
182
+ for (const existingPage of this._tabPages.values()) {
183
+ if (existingPage === page)
184
+ return;
185
+ }
186
+ if (page.isClosed()) {
187
+ logger.debug({ tabId }, "Tab is closed, skipping");
188
+ return;
189
+ }
190
+ let cdpSession = null;
191
+ try {
192
+ logger.debug({ tabId }, "Setting up recording for tab");
193
+ cdpSession = await page.context().newCDPSession(page);
194
+ await cdpSession.send("Runtime.enable");
195
+ await cdpSession.send("Page.enable");
196
+ await cdpSession.send("Runtime.addBinding", { name: "reportUserBehavior" });
197
+ cdpSession.on("Runtime.bindingCalled", (event) => {
198
+ this._handleBindingEvent(event, tabId);
199
+ });
200
+ cdpSession.on("Page.frameNavigated", (event) => {
201
+ this._handleNavigation(event, tabId);
202
+ });
203
+ const script = getTrackerScript();
204
+ await cdpSession.send("Page.addScriptToEvaluateOnNewDocument", {
205
+ source: script,
206
+ runImmediately: true,
207
+ });
208
+ try {
209
+ await page.evaluate(script);
210
+ }
211
+ catch (e) {
212
+ logger.debug({ err: e }, "Could not inject script immediately");
213
+ }
214
+ const responseListener = (response) => {
215
+ this._handleResponse(response, tabId);
216
+ };
217
+ page.on("response", responseListener);
218
+ this._responseListeners.set(tabId, responseListener);
219
+ this._monitoredTabs.add(tabId);
220
+ this._tabPages.set(tabId, page);
221
+ this._cdpSessions.set(tabId, cdpSession);
222
+ this._recordInitialNavigation(tabId, page);
223
+ logger.info({ tabId }, "Recording setup complete for tab");
224
+ }
225
+ catch (e) {
226
+ // Clean up CDP session on partial failure to prevent leak
227
+ if (cdpSession) {
228
+ try {
229
+ await cdpSession.detach();
230
+ }
231
+ catch { /* best effort */ }
232
+ }
233
+ logger.error({ tabId, err: e }, "Failed to setup recording for tab");
234
+ }
235
+ }
236
+ _recordInitialNavigation(tabId, page) {
237
+ try {
238
+ const url = page.url();
239
+ if (!url || url === "about:blank" || url.startsWith("chrome://"))
240
+ return;
241
+ this._handleNavigation({ frame: { url } }, tabId);
242
+ }
243
+ catch {
244
+ // ignore
245
+ }
246
+ }
247
+ // ===== Event Handling =====
248
+ _handleBindingEvent(event, tabId) {
249
+ if (event.name !== "reportUserBehavior")
250
+ return;
251
+ const payload = event.payload;
252
+ this._processOperation(payload, tabId).catch((e) => {
253
+ logger.debug({ err: e }, "Error processing binding event");
254
+ });
255
+ }
256
+ async _processOperation(payload, tabId) {
257
+ try {
258
+ const data = JSON.parse(payload);
259
+ if (!data.type) {
260
+ logger.warn("Invalid operation: missing type");
261
+ return;
262
+ }
263
+ if (data.type === "navigate") {
264
+ const navUrl = data.url || "";
265
+ const now = Date.now();
266
+ if (this._lastNavUrl && this._lastNavTime) {
267
+ const timeDiff = now - this._lastNavTime;
268
+ if (navUrl === this._lastNavUrl && timeDiff < this._navDedupMs) {
269
+ logger.debug({ url: navUrl }, "Duplicate navigate filtered");
270
+ return;
271
+ }
272
+ }
273
+ this._lastNavUrl = navUrl;
274
+ this._lastNavTime = now;
275
+ }
276
+ if (data.type === "scroll") {
277
+ this._lastScrollTime = Date.now();
278
+ }
279
+ data.tab_id = tabId;
280
+ if (this.operations.length >= MAX_OPERATIONS) {
281
+ logger.warn({ max: MAX_OPERATIONS }, "Operations cap reached — dropping oldest");
282
+ this.operations.splice(0, 1000); // drop oldest 1000
283
+ }
284
+ this.operations.push(data);
285
+ this._logOperation(data);
286
+ if (this._operationCallback) {
287
+ try {
288
+ this._operationCallback(data);
289
+ }
290
+ catch (e) {
291
+ logger.warn({ err: e }, "Operation callback failed");
292
+ }
293
+ }
294
+ if (this._enableSnapshotCapture && data.type === "navigate") {
295
+ const url = data.url || "";
296
+ if (url && url !== "about:blank" && !url.startsWith("chrome://")) {
297
+ this._captureSnapshot(url, tabId).catch(() => { });
298
+ }
299
+ }
300
+ }
301
+ catch (e) {
302
+ logger.warn({ err: e }, "Failed to parse operation data");
303
+ }
304
+ }
305
+ _handleNavigation(event, tabId) {
306
+ const frame = event.frame || {};
307
+ const url = frame.url;
308
+ const parentId = frame.parentId;
309
+ if (parentId !== undefined)
310
+ return;
311
+ if (!url || url === "about:blank" || url.startsWith("chrome://"))
312
+ return;
313
+ logger.debug({ tabId, url }, "CDP navigation detected");
314
+ const navPayload = JSON.stringify({
315
+ type: "navigate",
316
+ timestamp: new Date().toISOString(),
317
+ url,
318
+ });
319
+ this._processOperation(navPayload, tabId).catch(() => { });
320
+ }
321
+ // ===== Dataload Detection =====
322
+ _handleResponse(response, tabId) {
323
+ if (!this._isRecording)
324
+ return;
325
+ this._processResponse(response, tabId).catch(() => { });
326
+ }
327
+ async _processResponse(response, tabId) {
328
+ try {
329
+ if (!this._lastScrollTime)
330
+ return;
331
+ if (Date.now() - this._lastScrollTime > this._dataloadWindowMs)
332
+ return;
333
+ const request = response.request();
334
+ const resourceType = request.resourceType();
335
+ if (resourceType !== "xhr" && resourceType !== "fetch")
336
+ return;
337
+ const status = response.status();
338
+ if (status < 200 || status >= 300)
339
+ return;
340
+ const contentType = (await response.allHeaders())["content-type"] || "";
341
+ if (!contentType.includes("application/json"))
342
+ return;
343
+ const requestUrl = request.url();
344
+ const urlBase = requestUrl.split("?")[0];
345
+ if (this._recentDataloadUrls.has(urlBase))
346
+ return;
347
+ this._recentDataloadUrls.add(urlBase);
348
+ const data = {
349
+ type: "dataload",
350
+ timestamp: new Date().toISOString(),
351
+ url: response.frame()?.url() || "",
352
+ request_url: requestUrl,
353
+ method: request.method(),
354
+ status,
355
+ tab_id: tabId,
356
+ };
357
+ if (this.operations.length >= MAX_OPERATIONS) {
358
+ this.operations.splice(0, 1000);
359
+ }
360
+ this.operations.push(data);
361
+ this._logOperation(data);
362
+ if (this._operationCallback) {
363
+ try {
364
+ this._operationCallback(data);
365
+ }
366
+ catch (e) {
367
+ logger.warn({ err: e }, "Operation callback failed");
368
+ }
369
+ }
370
+ }
371
+ catch (e) {
372
+ logger.debug({ err: e }, "Error processing response");
373
+ }
374
+ }
375
+ // ===== Snapshot Capture =====
376
+ async _captureSnapshot(url, tabId) {
377
+ if (!this._browserSession || !this._enableSnapshotCapture)
378
+ return;
379
+ const urlHash = createHash("md5").update(url).digest("hex").slice(0, 12);
380
+ if (this.snapshots[urlHash])
381
+ return;
382
+ try {
383
+ await new Promise((r) => setTimeout(r, 1000));
384
+ let page = this._tabPages.get(tabId);
385
+ if ((!page || page.isClosed()) && this._browserSession) {
386
+ page = this._browserSession.pages.get(tabId);
387
+ }
388
+ if (!page || page.isClosed())
389
+ return;
390
+ if (this._browserSession.snapshot &&
391
+ this._browserSession.currentTabId === tabId) {
392
+ try {
393
+ const snapshotResult = await this._browserSession.snapshot.getFullResult();
394
+ if (snapshotResult) {
395
+ this.snapshots[urlHash] = {
396
+ url,
397
+ snapshot_text: snapshotResult.snapshotText,
398
+ captured_at: new Date().toISOString(),
399
+ };
400
+ logger.info({ url: url.slice(0, 60) }, "Snapshot captured");
401
+ return;
402
+ }
403
+ }
404
+ catch (e) {
405
+ logger.debug({ url, err: e }, "Full snapshot capture failed; falling back to simple snapshot");
406
+ }
407
+ }
408
+ const domContent = await page.evaluate(() => ({
409
+ title: document.title,
410
+ url: window.location.href,
411
+ }));
412
+ this.snapshots[urlHash] = {
413
+ url,
414
+ simple: domContent,
415
+ captured_at: new Date().toISOString(),
416
+ };
417
+ logger.info({ url: url.slice(0, 60) }, "Simple snapshot captured");
418
+ }
419
+ catch (e) {
420
+ logger.warn({ url, err: e }, "Failed to capture snapshot");
421
+ }
422
+ }
423
+ // ===== Logging =====
424
+ _logOperation(data) {
425
+ const opType = (data.type || "unknown").toUpperCase();
426
+ const ref = data.ref || "";
427
+ const text = data.text ? data.text.slice(0, 30) : "";
428
+ const parts = [`${opType}`];
429
+ if (ref)
430
+ parts.push(`ref=${ref}`);
431
+ if (text)
432
+ parts.push(`text="${text}"`);
433
+ if (data.value)
434
+ parts.push(`value="${String(data.value).slice(0, 30)}"`);
435
+ if (data.url && opType === "NAVIGATE")
436
+ parts.push(`url=${data.url.slice(0, 50)}`);
437
+ if (data.request_url && opType === "DATALOAD")
438
+ parts.push(`request=${data.request_url.slice(0, 60)}`);
439
+ logger.debug({ operation: parts.join(" ") }, "Recorded operation");
440
+ }
441
+ }
442
+ //# sourceMappingURL=behavior-recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-recorder.js","sourceRoot":"","sources":["../../../src/browser/behavior-recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * BrowserSession — Multi-mode browser automation engine.
3
+ *
4
+ * Connection modes:
5
+ * - 'standalone': Launch new Chromium instance
6
+ * - 'cdp': Connect to existing browser via CDP
7
+ * - 'managed': Persistent browser profile (launchPersistentContext)
8
+ *
9
+ * Key concepts:
10
+ * - Tab management (Map<tabId, Page>), Tab Groups
11
+ * - Singleton per session-id, factory method create()
12
+ * - Popup event listening, crash handling
13
+ * - getSnapshot(), execAction(), visit()
14
+ */
15
+ import { type Page } from "playwright";
16
+ import { PageSnapshot } from "./page-snapshot.js";
17
+ import { ActionExecutor } from "./action-executor.js";
18
+ import type { AriseBrowserConfig, ActionResult, TabInfo, SessionRef } from "../types/index.js";
19
+ type PageTextMode = "auto" | "raw" | "list" | "article" | "table" | "readability";
20
+ export interface PageModelInput {
21
+ type?: string;
22
+ label?: string;
23
+ placeholder?: string;
24
+ name?: string;
25
+ value?: string;
26
+ context?: string;
27
+ }
28
+ export interface PageModelCard {
29
+ title: string;
30
+ url?: string;
31
+ price?: string;
32
+ location?: string;
33
+ meta?: string;
34
+ }
35
+ export interface PageModelListSummary {
36
+ totalResults?: string;
37
+ querySummary?: string;
38
+ visibleCards: number;
39
+ hiddenVisibleCards: number;
40
+ strongCardCount: number;
41
+ score: number;
42
+ cards: PageModelCard[];
43
+ }
44
+ export interface PageModelTableSummary {
45
+ caption?: string;
46
+ columns: string[];
47
+ rows: string[][];
48
+ visibleRows: number;
49
+ score: number;
50
+ calendarLike: boolean;
51
+ }
52
+ export interface PageModelArticleSummary {
53
+ title?: string;
54
+ paragraphs: string[];
55
+ score: number;
56
+ }
57
+ export interface PageModel {
58
+ primaryContent: "result_list" | "table" | "article" | "form" | "generic";
59
+ confidence: number;
60
+ querySummary?: string;
61
+ queryParams: Record<string, string>;
62
+ filtersVisible: boolean;
63
+ visibleInputs: PageModelInput[];
64
+ auxiliarySections: string[];
65
+ listSummary?: PageModelListSummary;
66
+ tableSummary?: PageModelTableSummary;
67
+ articleSummary?: PageModelArticleSummary;
68
+ rawText?: string;
69
+ }
70
+ interface EvaluationConsoleEntry {
71
+ type: string;
72
+ text: string;
73
+ }
74
+ interface EvaluationDetailedResult {
75
+ result: unknown;
76
+ console: EvaluationConsoleEntry[];
77
+ }
78
+ interface TabGroup {
79
+ taskId: string;
80
+ title: string;
81
+ color: string;
82
+ tabs: Map<string, Page>;
83
+ currentTabId?: string;
84
+ }
85
+ type PageRegisteredListener = (tabId: string, page: Page) => void | Promise<void>;
86
+ export declare class BrowserSession implements SessionRef {
87
+ private static _instances;
88
+ private _browser;
89
+ private _context;
90
+ private _pages;
91
+ private _page;
92
+ private _currentTabId;
93
+ private _snapshotCache;
94
+ private _executorCache;
95
+ private _pageIds;
96
+ private _pageListeners;
97
+ private _pageRegisteredListeners;
98
+ private _contextListenersAttached;
99
+ /** Patched UA string for CDP-level override (covers Web Workers). */
100
+ private _patchedUa;
101
+ private _tabGroups;
102
+ private _colorIndex;
103
+ snapshot: PageSnapshot | null;
104
+ executor: ActionExecutor | null;
105
+ private _connectPromise;
106
+ private _sessionId;
107
+ private _config;
108
+ private constructor();
109
+ get sessionId(): string;
110
+ get isConnected(): boolean;
111
+ get currentPage(): Page | null;
112
+ get currentTabId(): string | null;
113
+ /** Public getter for pages map (used by BehaviorRecorder). */
114
+ get pages(): ReadonlyMap<string, Page>;
115
+ onPageRegistered(listener: PageRegisteredListener): () => void;
116
+ private _getSnapshotForPage;
117
+ private _getExecutorForPage;
118
+ private _attachCurrentPage;
119
+ private _emitPageRegistered;
120
+ private _registerPage;
121
+ private _resolvePage;
122
+ private _normalizeNavigationTimeout;
123
+ private _remainingTimeout;
124
+ private _navigatePage;
125
+ static create(config: AriseBrowserConfig, sessionId?: string): BrowserSession;
126
+ static getInstance(sessionId: string): BrowserSession | null;
127
+ ensureBrowser(): Promise<void>;
128
+ /**
129
+ * Try local Chrome first, then Playwright's bundled Chromium.
130
+ * Avoids requiring `npx playwright install` when Chrome is already installed.
131
+ */
132
+ private _launchStandalone;
133
+ private _doConnect;
134
+ /** Unified tab cleanup — removes from _pages, tab groups, and picks next tab if needed. */
135
+ private _cleanupTab;
136
+ private _setupContextListeners;
137
+ private _setupPageListeners;
138
+ private _handleNewPage;
139
+ getPage(): Promise<Page>;
140
+ getPageForTab(tabId?: string, options?: {
141
+ createIfMissing?: boolean;
142
+ }): Promise<Page | null>;
143
+ getPageInfo(tabId?: string): Promise<{
144
+ tabId: string | null;
145
+ url: string;
146
+ title: string;
147
+ }>;
148
+ visit(url: string, options?: {
149
+ tabId?: string;
150
+ timeout?: number;
151
+ }): Promise<string>;
152
+ getSnapshot(options?: {
153
+ tabId?: string;
154
+ forceRefresh?: boolean;
155
+ diffOnly?: boolean;
156
+ viewportLimit?: boolean;
157
+ }): Promise<string>;
158
+ getSnapshotWithElements(options?: {
159
+ tabId?: string;
160
+ viewportLimit?: boolean;
161
+ }): Promise<Record<string, unknown>>;
162
+ getLastElements(tabId?: string): Record<string, unknown>;
163
+ execAction(action: Record<string, unknown>, tabId?: string): Promise<ActionResult>;
164
+ getTabInfo(): Promise<TabInfo[]>;
165
+ switchToTab(tabId: string): Promise<boolean>;
166
+ closeTab(tabId: string): Promise<boolean>;
167
+ createNewTab(url?: string, options?: {
168
+ timeout?: number;
169
+ }): Promise<[string, Page]>;
170
+ createTabGroup(taskId: string, title?: string): Promise<TabGroup>;
171
+ createTabInGroup(taskId: string, url?: string, options?: {
172
+ timeout?: number;
173
+ }): Promise<[string, Page]>;
174
+ closeTabGroup(taskId: string): Promise<boolean>;
175
+ getTabGroupsInfo(): Record<string, unknown>[];
176
+ takeScreenshot(options?: {
177
+ tabId?: string;
178
+ type?: "jpeg" | "png";
179
+ quality?: number;
180
+ }): Promise<Buffer | null>;
181
+ exportPdf(tabId?: string): Promise<Buffer | null>;
182
+ getPageModel(tabId?: string, options?: {
183
+ includeRawText?: boolean;
184
+ }): Promise<PageModel>;
185
+ getPageText(tabId?: string, mode?: PageTextMode): Promise<string>;
186
+ evaluate(expression: string, tabId?: string): Promise<unknown>;
187
+ evaluateDetailed(expression: string, tabId?: string, options?: {
188
+ captureConsole?: boolean;
189
+ }): Promise<EvaluationDetailedResult>;
190
+ getCookies(urls?: string[]): Promise<Record<string, unknown>[]>;
191
+ setCookies(cookies: Array<{
192
+ name: string;
193
+ value: string;
194
+ url?: string;
195
+ domain?: string;
196
+ path?: string;
197
+ }>): Promise<void>;
198
+ close(): Promise<void>;
199
+ static closeAllSessions(): Promise<void>;
200
+ }
201
+ export {};
202
+ //# sourceMappingURL=browser-session.d.ts.map