opensteer 0.6.13 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +256 -184
  2. package/dist/chunk-PQYA6IX2.js +32571 -0
  3. package/dist/chunk-PQYA6IX2.js.map +1 -0
  4. package/dist/cli/bin.cjs +38201 -0
  5. package/dist/cli/bin.cjs.map +1 -0
  6. package/dist/cli/bin.d.cts +1 -0
  7. package/dist/cli/bin.d.ts +1 -0
  8. package/dist/cli/bin.js +5612 -0
  9. package/dist/cli/bin.js.map +1 -0
  10. package/dist/index.cjs +31309 -16009
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +4440 -670
  13. package/dist/index.d.ts +4440 -670
  14. package/dist/index.js +438 -378
  15. package/dist/index.js.map +1 -0
  16. package/package.json +56 -62
  17. package/skills/README.md +21 -20
  18. package/skills/opensteer/SKILL.md +60 -194
  19. package/skills/opensteer/references/cli-reference.md +69 -113
  20. package/skills/opensteer/references/request-workflow.md +81 -0
  21. package/skills/opensteer/references/sdk-reference.md +101 -154
  22. package/CHANGELOG.md +0 -75
  23. package/bin/opensteer.mjs +0 -1423
  24. package/dist/browser-profile-client-CGXc0-P9.d.cts +0 -228
  25. package/dist/browser-profile-client-DHLzMf-K.d.ts +0 -228
  26. package/dist/chunk-2ES46WCO.js +0 -1437
  27. package/dist/chunk-3H5RRIMZ.js +0 -69
  28. package/dist/chunk-AVXUMEDG.js +0 -62
  29. package/dist/chunk-DN3GI5CH.js +0 -57
  30. package/dist/chunk-FAHE5DB2.js +0 -190
  31. package/dist/chunk-HBTSQ2V4.js +0 -15259
  32. package/dist/chunk-K5CL76MG.js +0 -81
  33. package/dist/chunk-U724TBY6.js +0 -1262
  34. package/dist/chunk-ZRCFF546.js +0 -77
  35. package/dist/cli/auth.cjs +0 -2022
  36. package/dist/cli/auth.d.cts +0 -114
  37. package/dist/cli/auth.d.ts +0 -114
  38. package/dist/cli/auth.js +0 -15
  39. package/dist/cli/local-profile.cjs +0 -197
  40. package/dist/cli/local-profile.d.cts +0 -18
  41. package/dist/cli/local-profile.d.ts +0 -18
  42. package/dist/cli/local-profile.js +0 -97
  43. package/dist/cli/profile.cjs +0 -18548
  44. package/dist/cli/profile.d.cts +0 -79
  45. package/dist/cli/profile.d.ts +0 -79
  46. package/dist/cli/profile.js +0 -1328
  47. package/dist/cli/server.cjs +0 -17232
  48. package/dist/cli/server.d.cts +0 -2
  49. package/dist/cli/server.d.ts +0 -2
  50. package/dist/cli/server.js +0 -977
  51. package/dist/cli/skills-installer.cjs +0 -230
  52. package/dist/cli/skills-installer.d.cts +0 -28
  53. package/dist/cli/skills-installer.d.ts +0 -28
  54. package/dist/cli/skills-installer.js +0 -201
  55. package/dist/extractor-4Q3TFZJB.js +0 -8
  56. package/dist/resolver-MGN64KCP.js +0 -7
  57. package/dist/types-Cr10igF3.d.cts +0 -345
  58. package/dist/types-Cr10igF3.d.ts +0 -345
  59. package/skills/electron/SKILL.md +0 -87
  60. package/skills/electron/references/opensteer-electron-recipes.md +0 -88
  61. package/skills/electron/references/opensteer-electron-workflow.md +0 -85
  62. package/skills/opensteer/references/examples.md +0 -118
package/dist/index.js CHANGED
@@ -1,410 +1,470 @@
1
- import {
2
- BrowserProfileClient
3
- } from "./chunk-ZRCFF546.js";
4
- import {
5
- ActionWsClient,
6
- BrowserPool,
7
- CounterResolutionError,
8
- CursorController,
9
- ElementPathError,
10
- LocalSelectorStorage,
11
- OPENSTEER_HIDDEN_ATTR,
12
- OPENSTEER_INTERACTIVE_ATTR,
13
- OPENSTEER_SCROLLABLE_ATTR,
14
- OS_BOUNDARY_ATTR,
15
- OS_IFRAME_BOUNDARY_TAG,
16
- OS_NODE_ID_ATTR,
17
- OS_SHADOW_BOUNDARY_TAG,
18
- OS_UNAVAILABLE_ATTR,
19
- Opensteer,
20
- OpensteerActionError,
21
- OpensteerAgentActionError,
22
- OpensteerAgentApiError,
23
- OpensteerAgentBusyError,
24
- OpensteerAgentConfigError,
25
- OpensteerAgentError,
26
- OpensteerAgentExecutionError,
27
- OpensteerAgentProviderError,
28
- OpensteerCuaAgentHandler,
29
- SvgCursorRenderer,
30
- buildArrayFieldPathCandidates,
31
- buildElementPathFromHandle,
32
- buildElementPathFromSelector,
33
- buildPathSelectorHint,
34
- cleanForAction,
35
- cleanForClickable,
36
- cleanForExtraction,
37
- cleanForFull,
38
- cleanForScrollable,
39
- clearCookies,
40
- clearPersistentProfileSingletons,
41
- cloneElementPath,
42
- closeTab,
43
- collectLocalSelectorCacheEntries,
44
- countArrayItemsWithPath,
45
- createCuaClient,
46
- createEmptyRegistry,
47
- createIsolatedRuntimeProfile,
48
- createTab,
49
- exportCookies,
50
- extractArrayRowsWithPaths,
51
- extractArrayWithPaths,
52
- extractWithPaths,
53
- getCookies,
54
- getElementAttributes,
55
- getElementBoundingBox,
56
- getElementText,
57
- getElementValue,
58
- getOrCreatePersistentProfile,
59
- getOwnedRealBrowserProcessPolicy,
60
- getPageHtml,
61
- getPageTitle,
62
- hasActiveRuntimeProfileCreations,
63
- importCookies,
64
- listTabs,
65
- markInteractiveElements,
66
- performClick,
67
- performFileUpload,
68
- performHover,
69
- performInput,
70
- performScroll,
71
- performSelect,
72
- persistIsolatedRuntimeProfile,
73
- planSnappyCursorMotion,
74
- prepareSnapshot,
75
- pressKey,
76
- queryAllByElementPath,
77
- resolveAgentConfig,
78
- resolveCounterElement,
79
- resolveCountersBatch,
80
- resolveElementPath,
81
- sanitizeElementPath,
82
- serializePageHTML,
83
- setCookie,
84
- switchTab,
85
- typeText,
86
- waitForVisualStability
87
- } from "./chunk-HBTSQ2V4.js";
88
- import {
89
- CloudCdpClient,
90
- CloudSessionClient,
91
- OpensteerCloudError,
92
- cloudActionMethods,
93
- cloudErrorCodes,
94
- cloudNotLaunchedError,
95
- cloudSessionContractVersion,
96
- cloudSessionSourceTypes,
97
- cloudSessionStatuses,
98
- cloudUnsupportedMethodError,
99
- isCloudActionMethod,
100
- isCloudErrorCode,
101
- isCloudSessionSourceType,
102
- isCloudSessionStatus,
103
- normalizeNamespace,
104
- resolveNamespaceDir
105
- } from "./chunk-2ES46WCO.js";
106
- import {
107
- detectChromePaths,
108
- expandHome,
109
- listLocalChromeProfiles
110
- } from "./chunk-K5CL76MG.js";
111
- import {
112
- createResolveCallback
113
- } from "./chunk-DN3GI5CH.js";
114
- import {
115
- createExtractCallback
116
- } from "./chunk-AVXUMEDG.js";
117
- import "./chunk-3H5RRIMZ.js";
118
- import {
119
- getModelProvider
120
- } from "./chunk-FAHE5DB2.js";
1
+ import { createOpensteerSemanticRuntime, AttachedOpensteerSessionProxy, OpensteerSessionRuntime } from './chunk-PQYA6IX2.js';
2
+ export { CloudSessionProxy, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OPENSTEER_FILESYSTEM_ROOT_LAYOUT, OPENSTEER_FILESYSTEM_ROOT_VERSION, OpensteerAttachAmbiguousError, OpensteerCloudClient, OpensteerLocalProfileUnavailableError, OpensteerSessionRuntime, STABLE_PRIMARY_ATTR_KEYS, ServiceOperationScheduler, buildArrayFieldPathCandidates, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomRuntime, createFilesystemOpensteerRoot, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, detectInstalledBrowserBrands, discoverLocalCdpBrowsers, dispatchSemanticOperation, generateStealthInitScript, generateStealthProfile, getAllBrowserBrands, getBrowserBrand, inspectCdpEndpoint, inspectLocalBrowserProfile, isCurrentUrlField, isValidCssAttributeKey, listLocalChromeProfiles, normalizeExtractedValue, normalizeOpensteerExecutionMode, parseRequestEnvelope, resolveCloudConfig, resolveCookieCaptureStrategy, resolveDomActionBridge, resolveExtractedValueInContext, resolveOpensteerExecutionMode, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath, unlockLocalBrowserProfile } from './chunk-PQYA6IX2.js';
121
3
 
122
- // src/cursor/renderers/cdp-overlay.ts
123
- var PULSE_DELAY_MS = 30;
124
- var CdpOverlayCursorRenderer = class {
125
- page = null;
126
- session = null;
127
- active = false;
128
- reason = "disabled";
129
- lastMessage;
130
- lastPoint = null;
131
- async initialize(page) {
132
- this.page = page;
133
- if (page.isClosed()) {
134
- this.markInactive("page_closed");
135
- return;
4
+ // src/sdk/opensteer.ts
5
+ var Opensteer = class _Opensteer {
6
+ runtime;
7
+ ownership;
8
+ constructor(options = {}) {
9
+ this.runtime = createOpensteerSemanticRuntime({
10
+ runtimeOptions: options,
11
+ ...options.cloud === void 0 ? {} : { cloud: options.cloud }
12
+ });
13
+ this.ownership = "owned";
14
+ }
15
+ static attach(options = {}) {
16
+ return _Opensteer.fromRuntime(
17
+ new AttachedOpensteerSessionProxy({
18
+ ...options.name === void 0 ? {} : { name: options.name },
19
+ ...options.rootDir === void 0 ? {} : { rootDir: options.rootDir }
20
+ }),
21
+ "attached"
22
+ );
23
+ }
24
+ async open(input = {}) {
25
+ const normalized = typeof input === "string" ? { url: input } : input;
26
+ if (this.ownership === "attached") {
27
+ assertAttachedOpenInputAllowed(normalized);
136
28
  }
137
- await this.createSession();
29
+ return this.runtime.open(normalized);
138
30
  }
139
- isActive() {
140
- return this.active;
31
+ async listPages(input = {}) {
32
+ return this.runtime.listPages(input);
141
33
  }
142
- status() {
143
- return {
144
- enabled: true,
145
- active: this.active,
146
- reason: this.reason ? this.lastMessage ? `${this.reason}: ${this.lastMessage}` : this.reason : void 0
147
- };
34
+ async newPage(input = {}) {
35
+ return this.runtime.newPage(input);
148
36
  }
149
- async move(point, style) {
150
- await this.sendWithRecovery(async (session) => {
151
- await session.send("Overlay.highlightQuad", {
152
- quad: buildCursorQuad(point, style.size),
153
- color: toProtocolRgba(style.fillColor),
154
- outlineColor: toProtocolRgba(style.outlineColor)
155
- });
37
+ async activatePage(input) {
38
+ return this.runtime.activatePage(input);
39
+ }
40
+ async closePage(input = {}) {
41
+ return this.runtime.closePage(input);
42
+ }
43
+ async goto(input) {
44
+ return this.runtime.goto(typeof input === "string" ? { url: input } : input);
45
+ }
46
+ async evaluate(input) {
47
+ const normalized = typeof input === "string" ? {
48
+ script: input
49
+ } : input;
50
+ const result = await this.runtime.evaluate(normalized);
51
+ return result.value;
52
+ }
53
+ async evaluateJson(input) {
54
+ return this.evaluate(input);
55
+ }
56
+ async addInitScript(input) {
57
+ const normalized = typeof input === "string" ? {
58
+ script: input
59
+ } : input;
60
+ return this.runtime.addInitScript(normalized);
61
+ }
62
+ async snapshot(input = {}) {
63
+ const mode = typeof input === "string" ? input : input.mode;
64
+ return this.runtime.snapshot(mode === void 0 ? {} : { mode });
65
+ }
66
+ async click(input) {
67
+ const normalized = normalizeTargetOptions(input);
68
+ return this.runtime.click(normalized);
69
+ }
70
+ async hover(input) {
71
+ const normalized = normalizeTargetOptions(input);
72
+ return this.runtime.hover(normalized);
73
+ }
74
+ async input(input) {
75
+ const normalized = normalizeTargetOptions(input);
76
+ return this.runtime.input({
77
+ ...normalized,
78
+ text: input.text,
79
+ ...input.pressEnter === void 0 ? {} : { pressEnter: input.pressEnter }
156
80
  });
157
- this.lastPoint = point;
158
81
  }
159
- async pulse(point, style) {
160
- const pulseSize = style.size * style.pulseScale;
161
- const pulseFill = {
162
- ...style.fillColor,
163
- a: Math.min(1, style.fillColor.a * 0.14)
164
- };
165
- const pulseOutline = {
166
- ...style.haloColor,
167
- a: Math.min(1, style.haloColor.a * 0.9)
168
- };
169
- await this.sendWithRecovery(async (session) => {
170
- await session.send("Overlay.highlightQuad", {
171
- quad: buildCursorQuad(point, pulseSize),
172
- color: toProtocolRgba(pulseFill),
173
- outlineColor: toProtocolRgba(pulseOutline)
174
- });
82
+ async scroll(input) {
83
+ const normalized = normalizeTargetOptions(input);
84
+ return this.runtime.scroll({
85
+ ...normalized,
86
+ direction: input.direction,
87
+ amount: input.amount
175
88
  });
176
- await sleep(PULSE_DELAY_MS);
177
- await this.move(point, style);
178
- }
179
- async clear() {
180
- if (!this.session) return;
181
- try {
182
- await this.session.send("Overlay.hideHighlight");
183
- } catch {
184
- this.markInactive("cdp_detached");
185
- }
186
89
  }
187
- async dispose() {
188
- await this.cleanupSession();
189
- this.active = false;
190
- this.reason = "disabled";
191
- this.lastMessage = void 0;
192
- this.lastPoint = null;
193
- this.page = null;
194
- }
195
- async sendWithRecovery(operation) {
196
- if (!this.active || !this.session) return;
197
- try {
198
- await operation(this.session);
199
- } catch (error) {
200
- const message = error instanceof Error ? error.message : String(error);
201
- this.lastMessage = message;
202
- if (!isRecoverableProtocolError(message) || !this.page) {
203
- this.markInactive("renderer_error", message);
204
- return;
90
+ async extract(input) {
91
+ const result = await this.runtime.extract(input);
92
+ return result.data;
93
+ }
94
+ async queryNetwork(input = {}) {
95
+ return this.runtime.queryNetwork(input);
96
+ }
97
+ async waitForNetwork(input) {
98
+ const { timeoutMs, pollIntervalMs, ...query } = input;
99
+ const timeoutAt = Date.now() + (timeoutMs ?? 3e4);
100
+ const pollInterval = pollIntervalMs ?? 100;
101
+ while (true) {
102
+ const { records } = await this.runtime.queryNetwork({
103
+ ...query,
104
+ limit: 1
105
+ });
106
+ if (records[0] !== void 0) {
107
+ return records[0];
205
108
  }
206
- await this.createSession();
207
- if (!this.active || !this.session) {
208
- return;
109
+ if (Date.now() >= timeoutAt) {
110
+ throw new Error("waitForNetwork timed out");
111
+ }
112
+ await delay(pollInterval);
113
+ }
114
+ }
115
+ async waitForResponse(input) {
116
+ return this.waitForNetwork(input);
117
+ }
118
+ async waitForPage(input = {}) {
119
+ const baseline = new Set((await this.runtime.listPages()).pages.map((page) => page.pageRef));
120
+ const timeoutAt = Date.now() + (input.timeoutMs ?? 3e4);
121
+ const pollIntervalMs = input.pollIntervalMs ?? 100;
122
+ while (true) {
123
+ const { pages } = await this.runtime.listPages();
124
+ const match = pages.find((page) => {
125
+ if (baseline.has(page.pageRef)) {
126
+ return false;
127
+ }
128
+ if (input.openerPageRef !== void 0 && page.openerPageRef !== input.openerPageRef) {
129
+ return false;
130
+ }
131
+ if (input.urlIncludes !== void 0 && !page.url.includes(input.urlIncludes)) {
132
+ return false;
133
+ }
134
+ return true;
135
+ });
136
+ if (match !== void 0) {
137
+ return match;
209
138
  }
210
- try {
211
- await operation(this.session);
212
- } catch (retryError) {
213
- const retryMessage = retryError instanceof Error ? retryError.message : String(retryError);
214
- this.markInactive("renderer_error", retryMessage);
139
+ if (Date.now() >= timeoutAt) {
140
+ throw new Error("waitForPage timed out");
215
141
  }
142
+ await delay(pollIntervalMs);
216
143
  }
217
144
  }
218
- async createSession() {
219
- if (!this.page || this.page.isClosed()) {
220
- this.markInactive("page_closed");
145
+ async saveNetwork(input) {
146
+ return this.runtime.saveNetwork(input);
147
+ }
148
+ async minimizeNetwork(input) {
149
+ return this.runtime.minimizeNetwork(input);
150
+ }
151
+ async diffNetwork(input) {
152
+ return this.runtime.diffNetwork(input);
153
+ }
154
+ async probeNetwork(input) {
155
+ return this.runtime.probeNetwork(input);
156
+ }
157
+ async reverseDiscover(input = {}) {
158
+ return this.runtime.discoverReverse(input);
159
+ }
160
+ async reverseQuery(input) {
161
+ return this.runtime.queryReverse(input);
162
+ }
163
+ async createReversePackage(input) {
164
+ return this.runtime.createReversePackage(input);
165
+ }
166
+ async runReversePackage(input) {
167
+ return this.runtime.runReversePackage(input);
168
+ }
169
+ async reverseExport(input) {
170
+ return this.runtime.exportReverse(input);
171
+ }
172
+ async reverseReport(input) {
173
+ return this.runtime.getReverseReport(input);
174
+ }
175
+ async getReversePackage(input) {
176
+ return this.runtime.getReversePackage(input);
177
+ }
178
+ async listReversePackages(input = {}) {
179
+ return this.runtime.listReversePackages(input);
180
+ }
181
+ async patchReversePackage(input) {
182
+ return this.runtime.patchReversePackage(input);
183
+ }
184
+ async interactionCapture(input) {
185
+ return this.runtime.captureInteraction(input);
186
+ }
187
+ async getInteraction(input) {
188
+ return this.runtime.getInteraction(input);
189
+ }
190
+ async interactionDiff(input) {
191
+ return this.runtime.diffInteraction(input);
192
+ }
193
+ async interactionReplay(input) {
194
+ return this.runtime.replayInteraction(input);
195
+ }
196
+ async clearNetwork(input = {}) {
197
+ return this.runtime.clearNetwork(input);
198
+ }
199
+ async captureScripts(input = {}) {
200
+ return this.runtime.captureScripts(input);
201
+ }
202
+ async readArtifact(input) {
203
+ return this.runtime.readArtifact(input);
204
+ }
205
+ async beautifyScript(input) {
206
+ return this.runtime.beautifyScript(input);
207
+ }
208
+ async deobfuscateScript(input) {
209
+ return this.runtime.deobfuscateScript(input);
210
+ }
211
+ async sandboxScript(input) {
212
+ return this.runtime.sandboxScript(input);
213
+ }
214
+ async solveCaptcha(input) {
215
+ return this.runtime.solveCaptcha(input);
216
+ }
217
+ async getCookies(input = {}) {
218
+ return this.runtime.getCookies(input);
219
+ }
220
+ async getStorageSnapshot(input = {}) {
221
+ return this.runtime.getStorageSnapshot(input);
222
+ }
223
+ async writeRequestPlan(input) {
224
+ return this.runtime.writeRequestPlan(input);
225
+ }
226
+ async inferRequestPlan(input) {
227
+ return this.runtime.inferRequestPlan(input);
228
+ }
229
+ async getRequestPlan(input) {
230
+ return this.runtime.getRequestPlan(input);
231
+ }
232
+ async listRequestPlans(input = {}) {
233
+ return this.runtime.listRequestPlans(input);
234
+ }
235
+ async writeAuthRecipe(input) {
236
+ return this.runtime.writeAuthRecipe(input);
237
+ }
238
+ async writeRecipe(input) {
239
+ return this.runtime.writeRecipe(input);
240
+ }
241
+ async getAuthRecipe(input) {
242
+ return this.runtime.getAuthRecipe(input);
243
+ }
244
+ async getRecipe(input) {
245
+ return this.runtime.getRecipe(input);
246
+ }
247
+ async listAuthRecipes(input = {}) {
248
+ return this.runtime.listAuthRecipes(input);
249
+ }
250
+ async listRecipes(input = {}) {
251
+ return this.runtime.listRecipes(input);
252
+ }
253
+ async runAuthRecipe(input) {
254
+ return this.runtime.runAuthRecipe(input);
255
+ }
256
+ async runRecipe(input) {
257
+ return this.runtime.runRecipe(input);
258
+ }
259
+ async request(key, input = {}) {
260
+ return this.runtime.request({
261
+ key,
262
+ ...input
263
+ });
264
+ }
265
+ async rawRequest(input) {
266
+ return this.runtime.rawRequest(input);
267
+ }
268
+ async route(input) {
269
+ return this.requireOwnedInstrumentationRuntime("route").route(input);
270
+ }
271
+ async interceptScript(input) {
272
+ return this.requireOwnedInstrumentationRuntime("interceptScript").interceptScript(input);
273
+ }
274
+ async computerExecute(input) {
275
+ return this.runtime.computerExecute(input);
276
+ }
277
+ async close() {
278
+ return this.runtime.close();
279
+ }
280
+ async disconnect() {
281
+ if (this.ownership === "owned") {
282
+ await this.close();
221
283
  return;
222
284
  }
223
- await this.cleanupSession();
224
- try {
225
- const session = await this.page.context().newCDPSession(this.page);
226
- await session.send("DOM.enable");
227
- await session.send("Overlay.enable");
228
- this.session = session;
229
- this.active = true;
230
- this.reason = void 0;
231
- this.lastMessage = void 0;
232
- } catch (error) {
233
- const message = error instanceof Error ? error.message : String(error);
234
- this.markInactive(inferSetupReason(message), message);
235
- await this.cleanupSession();
285
+ if (isDisconnectableRuntime(this.runtime)) {
286
+ await this.runtime.disconnect();
236
287
  }
237
288
  }
238
- async cleanupSession() {
239
- const session = this.session;
240
- this.session = null;
241
- if (!session) return;
242
- try {
243
- await session.detach();
244
- } catch {
245
- }
289
+ static fromRuntime(runtime, ownership) {
290
+ const instance = Object.create(_Opensteer.prototype);
291
+ instance.runtime = runtime;
292
+ instance.ownership = ownership;
293
+ return instance;
246
294
  }
247
- markInactive(reason, message) {
248
- this.active = false;
249
- this.reason = reason;
250
- this.lastMessage = message;
295
+ requireOwnedInstrumentationRuntime(method) {
296
+ if (this.runtime instanceof OpensteerSessionRuntime) {
297
+ return this.runtime;
298
+ }
299
+ throw new Error(`${method}() is only available on owned local SDK sessions.`);
251
300
  }
252
301
  };
253
- function buildCursorQuad(point, size) {
254
- const x = point.x;
255
- const y = point.y;
256
- return [
257
- // Point 0: Tip (the hotspot)
258
- roundPointValue(x),
259
- roundPointValue(y),
260
- // Point 1: Right shoulder — extends right and down
261
- roundPointValue(x + size * 0.45),
262
- roundPointValue(y + size * 0.78),
263
- // Point 2: Tail — bottom of the cursor shaft
264
- roundPointValue(x + size * 0.12),
265
- roundPointValue(y + size * 1.3),
266
- // Point 3: Left edge — stays close to the shaft
267
- roundPointValue(x - size * 0.04),
268
- roundPointValue(y + size * 0.62)
269
- ];
302
+ function assertAttachedOpenInputAllowed(input) {
303
+ if (input.browser !== void 0 || input.context !== void 0 || input.name !== void 0) {
304
+ throw new Error(
305
+ "Opensteer.attach(...) reuses an existing session. open() may only receive url when attached."
306
+ );
307
+ }
270
308
  }
271
- function inferSetupReason(message) {
272
- const lowered = message.toLowerCase();
273
- if (lowered.includes("not supported") || lowered.includes("only supported") || lowered.includes("unknown command")) {
274
- return "unsupported";
309
+ function isDisconnectableRuntime(runtime) {
310
+ return "disconnect" in runtime;
311
+ }
312
+ function normalizeTargetOptions(input) {
313
+ const hasElement = input.element !== void 0;
314
+ const hasSelector = input.selector !== void 0;
315
+ if (hasElement && hasSelector) {
316
+ throw new Error("Specify exactly one of element, selector, or description.");
317
+ }
318
+ if (hasElement) {
319
+ return {
320
+ target: {
321
+ kind: "element",
322
+ element: input.element
323
+ },
324
+ ...input.description === void 0 ? {} : { persistAsDescription: input.description },
325
+ ...input.networkTag === void 0 ? {} : { networkTag: input.networkTag }
326
+ };
327
+ }
328
+ if (hasSelector) {
329
+ return {
330
+ target: {
331
+ kind: "selector",
332
+ selector: input.selector
333
+ },
334
+ ...input.description === void 0 ? {} : { persistAsDescription: input.description },
335
+ ...input.networkTag === void 0 ? {} : { networkTag: input.networkTag }
336
+ };
275
337
  }
276
- return "cdp_unavailable";
338
+ if (input.description === void 0) {
339
+ throw new Error("Specify exactly one of element, selector, or description.");
340
+ }
341
+ return {
342
+ target: {
343
+ kind: "description",
344
+ description: input.description
345
+ },
346
+ ...input.networkTag === void 0 ? {} : { networkTag: input.networkTag }
347
+ };
277
348
  }
278
- function isRecoverableProtocolError(message) {
279
- const lowered = message.toLowerCase();
280
- return lowered.includes("session closed") || lowered.includes("target closed") || lowered.includes("has been closed") || lowered.includes("detached");
349
+ function delay(ms) {
350
+ return new Promise((resolve) => setTimeout(resolve, ms));
281
351
  }
282
- function toProtocolRgba(color) {
352
+
353
+ // src/behavior/mouse.ts
354
+ function generateMousePath(input) {
355
+ const dx = input.end.x - input.start.x;
356
+ const dy = input.end.y - input.start.y;
357
+ const distance = Math.hypot(dx, dy);
358
+ const durationMs = input.durationMs ?? Math.max(180, Math.round(distance * 2.2));
359
+ const fps = input.fps ?? 60;
360
+ const jitter = input.jitter ?? 3;
361
+ const curvature = input.curvature ?? 0.3;
362
+ const frameCount = Math.max(2, Math.round(durationMs / 1e3 * fps));
363
+ const normal = distance === 0 ? { x: 0, y: 1 } : { x: -dy / distance, y: dx / distance };
364
+ const controlDistance = distance * curvature;
365
+ const control1 = {
366
+ x: input.start.x + dx * 0.33 + normal.x * controlDistance,
367
+ y: input.start.y + dy * 0.33 + normal.y * controlDistance
368
+ };
369
+ const control2 = {
370
+ x: input.start.x + dx * 0.66 - normal.x * controlDistance * 0.6,
371
+ y: input.start.y + dy * 0.66 - normal.y * controlDistance * 0.6
372
+ };
373
+ const points = [];
374
+ for (let index = 0; index <= frameCount; index += 1) {
375
+ const linear = index / frameCount;
376
+ const eased = easeInOutCubic(linear);
377
+ const base = cubicBezier(input.start, control1, control2, input.end, eased);
378
+ const noise = index === 0 || index === frameCount ? 0 : gaussianRandom() * jitter;
379
+ points.push({
380
+ x: base.x + normal.x * noise,
381
+ y: base.y + normal.y * noise,
382
+ t: Math.round(linear * durationMs)
383
+ });
384
+ }
283
385
  return {
284
- r: clampColor(color.r),
285
- g: clampColor(color.g),
286
- b: clampColor(color.b),
287
- a: clampAlpha(color.a)
386
+ points,
387
+ durationMs
288
388
  };
289
389
  }
290
- function clampColor(value) {
291
- return Math.min(255, Math.max(0, Math.round(value)));
390
+ function generateDragTrail(input) {
391
+ return generateMousePath({
392
+ start: input.start,
393
+ end: input.end,
394
+ ...input.durationMs === void 0 ? {} : { durationMs: input.durationMs },
395
+ ...input.fps === void 0 ? {} : { fps: input.fps },
396
+ jitter: 1.5,
397
+ curvature: 0.18
398
+ });
292
399
  }
293
- function clampAlpha(value) {
294
- const normalized = Number.isFinite(value) ? value : 1;
295
- return Math.min(1, Math.max(0, normalized));
400
+ function cubicBezier(start, control1, control2, end, t) {
401
+ const inverse = 1 - t;
402
+ return {
403
+ x: inverse ** 3 * start.x + 3 * inverse ** 2 * t * control1.x + 3 * inverse * t ** 2 * control2.x + t ** 3 * end.x,
404
+ y: inverse ** 3 * start.y + 3 * inverse ** 2 * t * control1.y + 3 * inverse * t ** 2 * control2.y + t ** 3 * end.y
405
+ };
296
406
  }
297
- function roundPointValue(value) {
298
- return Math.round(value * 100) / 100;
407
+ function easeInOutCubic(t) {
408
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
299
409
  }
300
- function sleep(ms) {
301
- return new Promise((resolve) => setTimeout(resolve, ms));
410
+ function gaussianRandom() {
411
+ let u = 0;
412
+ let v = 0;
413
+ while (u === 0) {
414
+ u = Math.random();
415
+ }
416
+ while (v === 0) {
417
+ v = Math.random();
418
+ }
419
+ return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
302
420
  }
303
- export {
304
- ActionWsClient,
305
- BrowserPool,
306
- BrowserProfileClient,
307
- CdpOverlayCursorRenderer,
308
- CloudCdpClient,
309
- CloudSessionClient,
310
- CounterResolutionError,
311
- CursorController,
312
- ElementPathError,
313
- LocalSelectorStorage,
314
- OPENSTEER_HIDDEN_ATTR,
315
- OPENSTEER_INTERACTIVE_ATTR,
316
- OPENSTEER_SCROLLABLE_ATTR,
317
- OS_BOUNDARY_ATTR,
318
- OS_IFRAME_BOUNDARY_TAG,
319
- OS_NODE_ID_ATTR,
320
- OS_SHADOW_BOUNDARY_TAG,
321
- OS_UNAVAILABLE_ATTR,
322
- Opensteer,
323
- OpensteerActionError,
324
- OpensteerAgentActionError,
325
- OpensteerAgentApiError,
326
- OpensteerAgentBusyError,
327
- OpensteerAgentConfigError,
328
- OpensteerAgentError,
329
- OpensteerAgentExecutionError,
330
- OpensteerAgentProviderError,
331
- OpensteerCloudError,
332
- OpensteerCuaAgentHandler,
333
- SvgCursorRenderer,
334
- buildArrayFieldPathCandidates,
335
- buildElementPathFromHandle,
336
- buildElementPathFromSelector,
337
- buildPathSelectorHint,
338
- cleanForAction,
339
- cleanForClickable,
340
- cleanForExtraction,
341
- cleanForFull,
342
- cleanForScrollable,
343
- clearCookies,
344
- clearPersistentProfileSingletons,
345
- cloneElementPath,
346
- closeTab,
347
- cloudActionMethods,
348
- cloudErrorCodes,
349
- cloudNotLaunchedError,
350
- cloudSessionContractVersion,
351
- cloudSessionSourceTypes,
352
- cloudSessionStatuses,
353
- cloudUnsupportedMethodError,
354
- collectLocalSelectorCacheEntries,
355
- countArrayItemsWithPath,
356
- createCuaClient,
357
- createEmptyRegistry,
358
- createExtractCallback,
359
- createIsolatedRuntimeProfile,
360
- createResolveCallback,
361
- createTab,
362
- detectChromePaths,
363
- expandHome,
364
- exportCookies,
365
- extractArrayRowsWithPaths,
366
- extractArrayWithPaths,
367
- extractWithPaths,
368
- getCookies,
369
- getElementAttributes,
370
- getElementBoundingBox,
371
- getElementText,
372
- getElementValue,
373
- getModelProvider,
374
- getOrCreatePersistentProfile,
375
- getOwnedRealBrowserProcessPolicy,
376
- getPageHtml,
377
- getPageTitle,
378
- hasActiveRuntimeProfileCreations,
379
- importCookies,
380
- isCloudActionMethod,
381
- isCloudErrorCode,
382
- isCloudSessionSourceType,
383
- isCloudSessionStatus,
384
- listLocalChromeProfiles,
385
- listTabs,
386
- markInteractiveElements,
387
- normalizeNamespace,
388
- performClick,
389
- performFileUpload,
390
- performHover,
391
- performInput,
392
- performScroll,
393
- performSelect,
394
- persistIsolatedRuntimeProfile,
395
- planSnappyCursorMotion,
396
- prepareSnapshot,
397
- pressKey,
398
- queryAllByElementPath,
399
- resolveAgentConfig,
400
- resolveCounterElement,
401
- resolveCountersBatch,
402
- resolveElementPath,
403
- resolveNamespaceDir,
404
- sanitizeElementPath,
405
- serializePageHTML,
406
- setCookie,
407
- switchTab,
408
- typeText,
409
- waitForVisualStability
410
- };
421
+
422
+ // src/behavior/typing.ts
423
+ function generateTypingCadence(input) {
424
+ const baseDelayMs = input.baseDelayMs ?? 75;
425
+ const jitterMs = input.jitterMs ?? 35;
426
+ const hesitationProbability = input.hesitationProbability ?? 0.08;
427
+ return [...input.text].map((character, index) => {
428
+ const previous = input.text[index - 1];
429
+ const punctuationPause = /[.,!?;:]/.test(previous ?? "") ? 90 : 0;
430
+ const whitespacePause = /\s/.test(character) ? 30 : 0;
431
+ const hesitation = Math.random() < hesitationProbability ? 120 + Math.random() * 180 : 0;
432
+ const jitter = (Math.random() * 2 - 1) * jitterMs;
433
+ return {
434
+ character,
435
+ delayMs: Math.max(
436
+ 10,
437
+ Math.round(baseDelayMs + punctuationPause + whitespacePause + hesitation + jitter)
438
+ )
439
+ };
440
+ });
441
+ }
442
+
443
+ // src/behavior/scroll.ts
444
+ function generateScrollPattern(input) {
445
+ const durationMs = input.durationMs ?? Math.max(220, Math.round(Math.abs(input.distancePx) * 0.9));
446
+ const fps = input.fps ?? 60;
447
+ const frames = Math.max(2, Math.round(durationMs / 1e3 * fps));
448
+ let previousDistance = 0;
449
+ const points = [];
450
+ for (let index = 0; index <= frames; index += 1) {
451
+ const progress = easeInOutQuad(index / frames);
452
+ const currentDistance = progress * input.distancePx;
453
+ points.push({
454
+ deltaY: Math.round(currentDistance - previousDistance),
455
+ t: Math.round(index / frames * durationMs)
456
+ });
457
+ previousDistance = currentDistance;
458
+ }
459
+ return {
460
+ points,
461
+ durationMs
462
+ };
463
+ }
464
+ function easeInOutQuad(t) {
465
+ return t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2;
466
+ }
467
+
468
+ export { Opensteer, generateDragTrail, generateMousePath, generateScrollPattern, generateTypingCadence };
469
+ //# sourceMappingURL=index.js.map
470
+ //# sourceMappingURL=index.js.map