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,454 @@
1
+ import { sendRouteError } from "../route-utils.js";
2
+ const INTERACTIVE_ROLES = new Set([
3
+ "link",
4
+ "button",
5
+ "textbox",
6
+ "checkbox",
7
+ "radio",
8
+ "combobox",
9
+ "select",
10
+ "menuitem",
11
+ "tab",
12
+ "switch",
13
+ "slider",
14
+ "spinbutton",
15
+ "searchbox",
16
+ "option",
17
+ "menuitemcheckbox",
18
+ "menuitemradio",
19
+ "treeitem",
20
+ ]);
21
+ const VALUE_ROLES = new Set([
22
+ "textbox",
23
+ "searchbox",
24
+ "combobox",
25
+ "select",
26
+ "spinbutton",
27
+ "slider",
28
+ ]);
29
+ function extractRoleFromCompactLine(line) {
30
+ const trimmed = line.trim();
31
+ // Current unified analyzer format: "- role \"name\" ... [ref=e123]"
32
+ const bulletMatch = trimmed.match(/^-\s+([a-z][a-z0-9_-]*)\b/i);
33
+ if (bulletMatch)
34
+ return bulletMatch[1].toLowerCase();
35
+ // Legacy compact format compatibility: "[ref=e123] role ..."
36
+ const legacyMatch = trimmed.match(/^\[ref=[^\]]+\]\s*([a-z][a-z0-9_-]*)\b/i);
37
+ if (legacyMatch)
38
+ return legacyMatch[1].toLowerCase();
39
+ return null;
40
+ }
41
+ function normalizeText(value) {
42
+ if (typeof value !== "string")
43
+ return "";
44
+ return value.replace(/\s+/g, " ").trim();
45
+ }
46
+ function escapeCompactText(value) {
47
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
48
+ }
49
+ function normalizeTextList(value) {
50
+ if (!Array.isArray(value))
51
+ return [];
52
+ return value
53
+ .map((item) => normalizeText(item))
54
+ .filter(Boolean);
55
+ }
56
+ function parseRefOrder(ref) {
57
+ const match = ref.match(/^e(\d+)$/i);
58
+ return match ? Number(match[1]) : Number.POSITIVE_INFINITY;
59
+ }
60
+ function isTruthyFlag(value) {
61
+ return value === true || value === "true";
62
+ }
63
+ function compactAccessibleName(role, value) {
64
+ let compact = normalizeText(value);
65
+ if (!compact || compact.length < 180 || !["link", "button"].includes(role)) {
66
+ return compact;
67
+ }
68
+ if (/\bselect flight\b/i.test(compact) || /\bround trip total\b/i.test(compact)) {
69
+ compact = compact
70
+ .replace(/\.\s+/g, " | ")
71
+ .replace(/\bUS dollars\b/gi, "USD")
72
+ .replace(/\bround trip total\b/gi, "RT total")
73
+ .replace(/\bTotal duration\b/gi, "duration")
74
+ .replace(/\bLayover \(\d+ of \d+\) is a\b/gi, "layover")
75
+ .replace(/\bSelect flight\b/gi, "")
76
+ .replace(/\s+\|\s+/g, " | ")
77
+ .trim();
78
+ }
79
+ return compact;
80
+ }
81
+ function isLowInformationLabel(value) {
82
+ if (!value)
83
+ return true;
84
+ if (value.length < 24)
85
+ return true;
86
+ if (/^\d{1,2}(?:[$\s].*)?$/.test(value))
87
+ return true;
88
+ return /^(next|previous|done|reset|close|apply|save)$/i.test(value);
89
+ }
90
+ function shouldIncludeTag(role, tagName, displayName) {
91
+ if (!tagName)
92
+ return false;
93
+ if (VALUE_ROLES.has(role))
94
+ return true;
95
+ if (role === "link" && tagName !== "a")
96
+ return true;
97
+ if (role === "button" && tagName !== "button")
98
+ return true;
99
+ return !displayName;
100
+ }
101
+ function buildCompactEntries(elements, interactiveOnly) {
102
+ return Object.entries(elements)
103
+ .filter(([, el]) => el && typeof el === "object")
104
+ .flatMap(([ref, el]) => {
105
+ const element = el;
106
+ const role = normalizeText(element.role).toLowerCase();
107
+ if (interactiveOnly && !INTERACTIVE_ROLES.has(role)) {
108
+ return [];
109
+ }
110
+ return [{
111
+ ref,
112
+ element,
113
+ role,
114
+ name: compactAccessibleName(role, normalizeText(element.name)),
115
+ href: normalizeText(element.href),
116
+ dialogLabel: normalizeText(element.dialogLabel),
117
+ widget: normalizeText(element.widget).toLowerCase(),
118
+ inViewport: !("inViewport" in element) || element.inViewport !== false,
119
+ occluded: isTruthyFlag(element.occluded),
120
+ hasValue: normalizeText(element.value).length > 0,
121
+ selected: isTruthyFlag(element.selected),
122
+ expanded: element.expanded !== undefined && element.expanded !== null,
123
+ }];
124
+ });
125
+ }
126
+ function detectDominantOverlay(entries) {
127
+ const calendarEntries = entries.filter((entry) => entry.widget === "calendar" && entry.inViewport);
128
+ if (calendarEntries.length >= 3) {
129
+ const dialogLabel = calendarEntries.find((entry) => entry.dialogLabel)?.dialogLabel;
130
+ return { widget: "calendar", ...(dialogLabel ? { dialogLabel } : {}) };
131
+ }
132
+ const dialogCounts = new Map();
133
+ for (const entry of entries) {
134
+ if (!entry.dialogLabel || !entry.inViewport || entry.occluded)
135
+ continue;
136
+ dialogCounts.set(entry.dialogLabel, (dialogCounts.get(entry.dialogLabel) || 0) + 1);
137
+ }
138
+ let bestLabel = "";
139
+ let bestCount = 0;
140
+ for (const [dialogLabel, count] of dialogCounts.entries()) {
141
+ if (count > bestCount) {
142
+ bestLabel = dialogLabel;
143
+ bestCount = count;
144
+ }
145
+ }
146
+ if (!bestLabel)
147
+ return null;
148
+ return { dialogLabel: bestLabel };
149
+ }
150
+ function isOverlayEntry(entry, overlay) {
151
+ if (!overlay)
152
+ return false;
153
+ if (overlay.widget && entry.widget === overlay.widget)
154
+ return true;
155
+ if (overlay.dialogLabel && entry.dialogLabel === overlay.dialogLabel)
156
+ return true;
157
+ return false;
158
+ }
159
+ function shouldKeepEntry(entry, overlay) {
160
+ if (!overlay)
161
+ return true;
162
+ if (isOverlayEntry(entry, overlay))
163
+ return true;
164
+ if (entry.occluded)
165
+ return false;
166
+ if (VALUE_ROLES.has(entry.role) && entry.hasValue)
167
+ return true;
168
+ return entry.selected || entry.expanded;
169
+ }
170
+ function getEntryPriority(entry, overlay) {
171
+ let priority = 0;
172
+ if (isOverlayEntry(entry, overlay))
173
+ priority += 5000;
174
+ if (entry.widget === "calendar")
175
+ priority += 3000;
176
+ if (entry.dialogLabel)
177
+ priority += 1800;
178
+ if (entry.selected)
179
+ priority += 900;
180
+ if (entry.expanded)
181
+ priority += 800;
182
+ if (VALUE_ROLES.has(entry.role) && entry.hasValue)
183
+ priority += 700;
184
+ if (entry.inViewport)
185
+ priority += 250;
186
+ if (!entry.occluded)
187
+ priority += 120;
188
+ if (entry.occluded)
189
+ priority -= 500;
190
+ if (entry.role === "button")
191
+ priority += 80;
192
+ if (entry.role === "textbox" || entry.role === "combobox" || entry.role === "searchbox") {
193
+ priority += 140;
194
+ }
195
+ if (entry.role === "link")
196
+ priority += 60;
197
+ return priority;
198
+ }
199
+ function buildCompactLine(ref, element, semanticMode, options) {
200
+ const role = normalizeText(element.role).toLowerCase() || "generic";
201
+ const accessibleNameRaw = normalizeText(element.name);
202
+ const placeholder = normalizeText(element.placeholder);
203
+ const value = normalizeText(element.value);
204
+ const tagName = normalizeText(element.tagName).toLowerCase();
205
+ const href = normalizeText(element.href);
206
+ const ariaLabelRaw = normalizeText(element.ariaLabel);
207
+ const dialogLabel = normalizeText(element.dialogLabel);
208
+ const monthLabel = normalizeText(element.monthLabel);
209
+ const widget = normalizeText(element.widget).toLowerCase();
210
+ const contextTrailRaw = normalizeTextList(element.contextTrail);
211
+ const fallbackName = !accessibleNameRaw && ["textbox", "searchbox", "combobox"].includes(role)
212
+ ? placeholder
213
+ : "";
214
+ const displayNameRaw = accessibleNameRaw || fallbackName;
215
+ const displayName = compactAccessibleName(role, displayNameRaw);
216
+ const ariaLabel = compactAccessibleName(role, ariaLabelRaw);
217
+ const lowInfoName = isLowInformationLabel(displayNameRaw || ariaLabelRaw);
218
+ const contextTrail = contextTrailRaw
219
+ .filter((item) => item !== displayNameRaw && item !== ariaLabelRaw)
220
+ .slice(0, lowInfoName ? 2 : 0);
221
+ const parts = [`- ${role}`];
222
+ if (displayName) {
223
+ parts.push(`"${escapeCompactText(displayName)}"`);
224
+ }
225
+ if (element.disabled === true)
226
+ parts.push("[disabled]");
227
+ if (element.checked !== undefined && element.checked !== null) {
228
+ parts.push(`checked=${String(element.checked)}`);
229
+ }
230
+ if (element.expanded !== undefined && element.expanded !== null) {
231
+ parts.push(`expanded=${String(element.expanded)}`);
232
+ }
233
+ if (semanticMode && element.selected === true)
234
+ parts.push("[selected]");
235
+ if (semanticMode && element.occluded === true)
236
+ parts.push("[occluded]");
237
+ if (semanticMode && element.inViewport === false)
238
+ parts.push("[viewport=off]");
239
+ const level = typeof element.level === "number"
240
+ ? element.level
241
+ : typeof element.level === "string"
242
+ ? Number(element.level)
243
+ : NaN;
244
+ if (Number.isInteger(level) && level > 0) {
245
+ parts.push(`[level=${level}]`);
246
+ }
247
+ parts.push(`[ref=${ref}]`);
248
+ if (element.receivesPointerEvents === true && element.hasPointerCursor === true) {
249
+ parts.push("[cursor=pointer]");
250
+ }
251
+ if (shouldIncludeTag(role, tagName, displayNameRaw)) {
252
+ parts.push(`[tag=${tagName}]`);
253
+ }
254
+ if (placeholder && placeholder !== displayName) {
255
+ parts.push(`[placeholder="${escapeCompactText(placeholder)}"]`);
256
+ }
257
+ if (value &&
258
+ value !== displayName &&
259
+ value !== placeholder &&
260
+ !["link", "button"].includes(role)) {
261
+ parts.push(`[value="${escapeCompactText(value)}"]`);
262
+ }
263
+ if (href) {
264
+ parts.push(`-> ${href}`);
265
+ }
266
+ if (semanticMode &&
267
+ ariaLabel &&
268
+ ariaLabelRaw !== displayNameRaw &&
269
+ (lowInfoName || VALUE_ROLES.has(role) || role === "tab")) {
270
+ parts.push(`[aria="${escapeCompactText(ariaLabel)}"]`);
271
+ }
272
+ if (semanticMode && widget) {
273
+ parts.push(`[widget=${widget}]`);
274
+ }
275
+ if (semanticMode && monthLabel) {
276
+ parts.push(`[month="${escapeCompactText(monthLabel)}"]`);
277
+ }
278
+ if (semanticMode && dialogLabel) {
279
+ parts.push(`[dialog="${escapeCompactText(dialogLabel)}"]`);
280
+ }
281
+ const shouldIncludeContext = contextTrail.length > 0
282
+ && (semanticMode
283
+ || (options?.includeLowInfoContext === true
284
+ && VALUE_ROLES.has(role)
285
+ && lowInfoName));
286
+ if (shouldIncludeContext) {
287
+ parts.push(`[context="${escapeCompactText(contextTrail.join(" | "))}"]`);
288
+ }
289
+ return parts.join(" ");
290
+ }
291
+ function normalizeHrefKey(value) {
292
+ return value.replace(/#.*$/, "").trim();
293
+ }
294
+ function isLowSignalResultListEntry(entry) {
295
+ if (entry.role === "button") {
296
+ return !entry.name && !entry.hasValue && !entry.selected && !entry.expanded;
297
+ }
298
+ if (entry.role === "link") {
299
+ return Boolean(entry.href) && !entry.name;
300
+ }
301
+ return false;
302
+ }
303
+ function buildResultListGroups(entries) {
304
+ const byHref = new Map();
305
+ for (const entry of entries) {
306
+ if (entry.role !== "link" || !entry.href)
307
+ continue;
308
+ const key = normalizeHrefKey(entry.href);
309
+ if (!key)
310
+ continue;
311
+ const list = byHref.get(key) ?? [];
312
+ list.push(entry);
313
+ byHref.set(key, list);
314
+ }
315
+ return [...byHref.entries()]
316
+ .map(([href, groupEntries]) => {
317
+ const sorted = [...groupEntries].sort((a, b) => b.name.length - a.name.length);
318
+ const named = sorted.find((entry) => entry.name.length >= 8) ?? sorted[0];
319
+ if (!named)
320
+ return null;
321
+ return {
322
+ href,
323
+ refs: groupEntries.map((entry) => entry.ref),
324
+ primaryRef: named.ref,
325
+ title: named.name || href,
326
+ };
327
+ })
328
+ .filter((group) => Boolean(group));
329
+ }
330
+ function buildResultListCompactLine(group, pageModel) {
331
+ const matchedCard = pageModel?.listSummary?.cards.find((card) => card.url && normalizeHrefKey(card.url) === group.href);
332
+ const parts = [`- link "${escapeCompactText(matchedCard?.title || group.title)}"`, `[ref=${group.primaryRef}]`];
333
+ if (matchedCard?.price)
334
+ parts.push(`[price="${escapeCompactText(matchedCard.price)}"]`);
335
+ if (matchedCard?.location)
336
+ parts.push(`[location="${escapeCompactText(matchedCard.location)}"]`);
337
+ if (matchedCard?.meta)
338
+ parts.push(`[meta="${escapeCompactText(matchedCard.meta)}"]`);
339
+ parts.push("-> " + group.href);
340
+ return parts.join(" ");
341
+ }
342
+ function buildCompactSnapshotFromElements(elements, interactiveOnly, semanticMode, pageModel) {
343
+ const entries = buildCompactEntries(elements, interactiveOnly);
344
+ const overlay = semanticMode ? detectDominantOverlay(entries) : null;
345
+ const sortEntries = (items) => [...items].sort((entryA, entryB) => {
346
+ const priorityA = getEntryPriority(entryA, overlay);
347
+ const priorityB = getEntryPriority(entryB, overlay);
348
+ if (priorityA !== priorityB)
349
+ return priorityB - priorityA;
350
+ const orderA = parseRefOrder(entryA.ref);
351
+ const orderB = parseRefOrder(entryB.ref);
352
+ if (orderA !== orderB)
353
+ return orderA - orderB;
354
+ return entryA.ref.localeCompare(entryB.ref);
355
+ });
356
+ const resultListMode = !overlay
357
+ && pageModel?.primaryContent === "result_list"
358
+ && (pageModel.listSummary?.cards.length ?? 0) >= 5;
359
+ if (resultListMode) {
360
+ const groups = buildResultListGroups(entries)
361
+ .filter((group) => pageModel?.listSummary?.cards.some((card) => card.url && normalizeHrefKey(card.url) === group.href));
362
+ const groupedRefs = new Set(groups.flatMap((group) => group.refs));
363
+ const controlLines = sortEntries(entries)
364
+ .filter((entry) => shouldKeepEntry(entry, overlay))
365
+ .filter((entry) => !groupedRefs.has(entry.ref))
366
+ .filter((entry) => !isLowSignalResultListEntry(entry))
367
+ .map((entry) => buildCompactLine(entry.ref, entry.element, semanticMode, {
368
+ includeLowInfoContext: pageModel?.filtersVisible === true,
369
+ }));
370
+ const cardLines = groups.map((group) => buildResultListCompactLine(group, pageModel));
371
+ return [...controlLines, ...cardLines].join("\n");
372
+ }
373
+ return sortEntries(entries)
374
+ .filter((entry) => shouldKeepEntry(entry, overlay))
375
+ .map((entry) => buildCompactLine(entry.ref, entry.element, semanticMode, {
376
+ includeLowInfoContext: pageModel?.filtersVisible === true,
377
+ }))
378
+ .join("\n");
379
+ }
380
+ export function registerSnapshotRoute(app) {
381
+ app.get("/snapshot", async (request, reply) => {
382
+ const session = app.session;
383
+ const { tabId, format = "yaml", diff, viewportLimit, filter } = request.query;
384
+ const diffOnly = diff === "true" || diff === "1";
385
+ const vpLimit = viewportLimit === "true" || viewportLimit === "1";
386
+ const semanticMode = request.query.semantic === "true" || request.query.semantic === "1";
387
+ const interactiveOnly = filter === "interactive";
388
+ try {
389
+ if (format === "json" || (format === "compact" && !diffOnly)) {
390
+ const result = await session.getSnapshotWithElements({ tabId, viewportLimit: vpLimit });
391
+ const elements = result.elements;
392
+ const pageModel = format === "compact"
393
+ ? await session.getPageModel(tabId, { includeRawText: false }).catch(() => undefined)
394
+ : undefined;
395
+ if (format === "compact") {
396
+ const compactText = buildCompactSnapshotFromElements(elements, interactiveOnly, semanticMode, pageModel);
397
+ if (compactText) {
398
+ return reply.type("text/plain").send(compactText);
399
+ }
400
+ }
401
+ // Convert to Pinchtab JSON format
402
+ const nodes = [];
403
+ let count = 0;
404
+ if (elements && typeof elements === "object") {
405
+ for (const [ref, el] of Object.entries(elements)) {
406
+ if (el && typeof el === "object") {
407
+ const elObj = el;
408
+ if (interactiveOnly && !INTERACTIVE_ROLES.has(String(elObj.role || ""))) {
409
+ continue;
410
+ }
411
+ nodes.push({ ref, ...elObj });
412
+ count++;
413
+ }
414
+ }
415
+ }
416
+ const info = await session.getPageInfo(tabId);
417
+ return {
418
+ nodes,
419
+ url: info.url,
420
+ title: info.title,
421
+ count,
422
+ };
423
+ }
424
+ // yaml / compact / text all return the snapshot text
425
+ const snapshotText = await session.getSnapshot({
426
+ tabId,
427
+ diffOnly,
428
+ viewportLimit: vpLimit,
429
+ });
430
+ if (format === "compact") {
431
+ let lines = snapshotText
432
+ .split("\n")
433
+ .filter((l) => l.includes("[ref="))
434
+ .map((l) => l.trim());
435
+ if (interactiveOnly) {
436
+ lines = lines.filter((l) => {
437
+ const role = extractRoleFromCompactLine(l);
438
+ return role ? INTERACTIVE_ROLES.has(role) : false;
439
+ });
440
+ }
441
+ return reply.type("text/plain").send(lines.join("\n"));
442
+ }
443
+ if (format === "text") {
444
+ return reply.type("text/plain").send(snapshotText);
445
+ }
446
+ // Default: yaml
447
+ return { snapshot: snapshotText, format: "yaml" };
448
+ }
449
+ catch (e) {
450
+ return sendRouteError(reply, e, "Snapshot capture failed");
451
+ }
452
+ });
453
+ }
454
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../src/server/routes/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export declare function registerTabLockRoute(app: FastifyInstance): void;
3
+ //# sourceMappingURL=tab-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab-lock.d.ts","sourceRoot":"","sources":["../../../../src/server/routes/tab-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAc/D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,QAiCxD"}
@@ -0,0 +1,30 @@
1
+ import { acquireLock, releaseLock, getLock } from "../../lock.js";
2
+ export function registerTabLockRoute(app) {
3
+ app.post("/tab/lock", async (request, reply) => {
4
+ const { tabId, owner, ttlMs } = request.body || {};
5
+ if (!tabId || !owner) {
6
+ return reply.code(400).send({ error: "tabId and owner are required" });
7
+ }
8
+ const lock = acquireLock(tabId, owner, ttlMs);
9
+ if (!lock) {
10
+ const existing = getLock(tabId);
11
+ return reply.code(409).send({
12
+ error: "Tab is already locked",
13
+ lock: existing,
14
+ });
15
+ }
16
+ return { tabId, lock };
17
+ });
18
+ app.post("/tab/unlock", async (request, reply) => {
19
+ const { tabId, owner } = request.body || {};
20
+ if (!tabId || !owner) {
21
+ return reply.code(400).send({ error: "tabId and owner are required" });
22
+ }
23
+ const released = releaseLock(tabId, owner);
24
+ if (!released) {
25
+ return reply.code(404).send({ error: "Lock not found or owner mismatch" });
26
+ }
27
+ return { tabId, released: true };
28
+ });
29
+ }
30
+ //# sourceMappingURL=tab-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab-lock.js","sourceRoot":"","sources":["../../../../src/server/routes/tab-lock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAalE,MAAM,UAAU,oBAAoB,CAAC,GAAoB;IACvD,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,OAA2C,EAAE,KAAK,EAAE,EAAE;QACjF,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,EAAc,CAAC;QAE/D,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,uBAAuB;gBAC9B,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,OAA6C,EAAE,KAAK,EAAE,EAAE;QACrF,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,EAAgB,CAAC;QAE1D,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export declare function registerTabRoute(app: FastifyInstance): void;
3
+ //# sourceMappingURL=tab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab.d.ts","sourceRoot":"","sources":["../../../../src/server/routes/tab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAW/D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,QAgDpD"}
@@ -0,0 +1,47 @@
1
+ import { getTabWriteConflict, sendRouteError, sendTabLocked } from "../route-utils.js";
2
+ export function registerTabRoute(app) {
3
+ app.post("/tab", async (request, reply) => {
4
+ const session = app.session;
5
+ const { action, tabId, url, owner } = request.body || {};
6
+ if (!action) {
7
+ return reply.code(400).send({ error: "action is required (create, close, switch)" });
8
+ }
9
+ try {
10
+ switch (action) {
11
+ case "create": {
12
+ const [newTabId] = await session.createNewTab(url);
13
+ await session.switchToTab(newTabId);
14
+ return { tabId: newTabId, action: "created" };
15
+ }
16
+ case "close": {
17
+ if (!tabId) {
18
+ return reply.code(400).send({ error: "tabId is required for close" });
19
+ }
20
+ const conflict = getTabWriteConflict(session, { tabId, owner });
21
+ if (conflict) {
22
+ return sendTabLocked(reply, conflict);
23
+ }
24
+ const closed = await session.closeTab(tabId);
25
+ return { tabId, action: "closed", success: closed };
26
+ }
27
+ case "switch": {
28
+ if (!tabId) {
29
+ return reply.code(400).send({ error: "tabId is required for switch" });
30
+ }
31
+ const conflict = getTabWriteConflict(session, { tabId, owner });
32
+ if (conflict) {
33
+ return sendTabLocked(reply, conflict);
34
+ }
35
+ const switched = await session.switchToTab(tabId);
36
+ return { tabId, action: "switched", success: switched };
37
+ }
38
+ default:
39
+ return reply.code(400).send({ error: `Unknown action: ${action}` });
40
+ }
41
+ }
42
+ catch (e) {
43
+ return sendRouteError(reply, e, "Tab operation failed");
44
+ }
45
+ });
46
+ }
47
+ //# sourceMappingURL=tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab.js","sourceRoot":"","sources":["../../../../src/server/routes/tab.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvF,MAAM,UAAU,gBAAgB,CAAC,GAAoB;IACnD,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAA0C,EAAE,KAAK,EAAE,EAAE;QAC3E,MAAM,OAAO,GAAI,GAAW,CAAC,OAAyB,CAAC;QACvD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,EAAa,CAAC;QAEpE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,CAAC;YACH,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;oBACnD,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;oBACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBAChD,CAAC;gBAED,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;oBACxE,CAAC;oBACD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;oBAChE,IAAI,QAAQ,EAAE,CAAC;wBACb,OAAO,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBACxC,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBACtD,CAAC;gBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;oBACzE,CAAC;oBACD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;oBAChE,IAAI,QAAQ,EAAE,CAAC;wBACb,OAAO,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBACxC,CAAC;oBACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;oBAClD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;gBAC1D,CAAC;gBAED;oBACE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,sBAAsB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export declare function registerTabsRoute(app: FastifyInstance): void;
3
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/server/routes/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,QAUrD"}
@@ -0,0 +1,13 @@
1
+ export function registerTabsRoute(app) {
2
+ app.get("/tabs", async (_request, reply) => {
3
+ const session = app.session;
4
+ try {
5
+ const tabs = await session.getTabInfo();
6
+ return { tabs };
7
+ }
8
+ catch (e) {
9
+ return reply.code(500).send({ error: "Failed to get tab info" });
10
+ }
11
+ });
12
+ }
13
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/server/routes/tabs.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACzC,MAAM,OAAO,GAAI,GAAW,CAAC,OAAyB,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YACxC,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export declare function registerTextRoute(app: FastifyInstance): void;
3
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../src/server/routes/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAS/D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,QAgBrD"}
@@ -0,0 +1,20 @@
1
+ import { sendRouteError } from "../route-utils.js";
2
+ export function registerTextRoute(app) {
3
+ app.get("/text", async (request, reply) => {
4
+ const session = app.session;
5
+ const { tabId, mode } = request.query;
6
+ try {
7
+ const text = await session.getPageText(tabId, mode || "auto");
8
+ const info = await session.getPageInfo(tabId);
9
+ return {
10
+ text,
11
+ url: info.url,
12
+ title: info.title,
13
+ };
14
+ }
15
+ catch (e) {
16
+ return sendRouteError(reply, e, "Failed to extract text");
17
+ }
18
+ });
19
+ }
20
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/server/routes/text.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAmD,EAAE,KAAK,EAAE,EAAE;QACpF,MAAM,OAAO,GAAI,GAAW,CAAC,OAAyB,CAAC;QACvD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,EAAG,IAAY,IAAI,MAAM,CAAC,CAAC;YACvE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO;gBACL,IAAI;gBACJ,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}