opensteer 0.6.12 → 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 +31342 -14617
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +4437 -658
  13. package/dist/index.d.ts +4437 -658
  14. package/dist/index.js +438 -374
  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-K5CL76MG.js +0 -81
  32. package/dist/chunk-RC4IPQDZ.js +0 -13828
  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 -17869
  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 -16553
  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,406 +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
- getPageHtml,
60
- getPageTitle,
61
- importCookies,
62
- listTabs,
63
- markInteractiveElements,
64
- performClick,
65
- performFileUpload,
66
- performHover,
67
- performInput,
68
- performScroll,
69
- performSelect,
70
- persistIsolatedRuntimeProfile,
71
- planSnappyCursorMotion,
72
- prepareSnapshot,
73
- pressKey,
74
- queryAllByElementPath,
75
- resolveAgentConfig,
76
- resolveCounterElement,
77
- resolveCountersBatch,
78
- resolveElementPath,
79
- sanitizeElementPath,
80
- serializePageHTML,
81
- setCookie,
82
- switchTab,
83
- typeText,
84
- waitForVisualStability
85
- } from "./chunk-RC4IPQDZ.js";
86
- import {
87
- CloudCdpClient,
88
- CloudSessionClient,
89
- OpensteerCloudError,
90
- cloudActionMethods,
91
- cloudErrorCodes,
92
- cloudNotLaunchedError,
93
- cloudSessionContractVersion,
94
- cloudSessionSourceTypes,
95
- cloudSessionStatuses,
96
- cloudUnsupportedMethodError,
97
- isCloudActionMethod,
98
- isCloudErrorCode,
99
- isCloudSessionSourceType,
100
- isCloudSessionStatus,
101
- normalizeNamespace,
102
- resolveNamespaceDir
103
- } from "./chunk-2ES46WCO.js";
104
- import {
105
- detectChromePaths,
106
- expandHome,
107
- listLocalChromeProfiles
108
- } from "./chunk-K5CL76MG.js";
109
- import {
110
- createResolveCallback
111
- } from "./chunk-DN3GI5CH.js";
112
- import {
113
- createExtractCallback
114
- } from "./chunk-AVXUMEDG.js";
115
- import "./chunk-3H5RRIMZ.js";
116
- import {
117
- getModelProvider
118
- } 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';
119
3
 
120
- // src/cursor/renderers/cdp-overlay.ts
121
- var PULSE_DELAY_MS = 30;
122
- var CdpOverlayCursorRenderer = class {
123
- page = null;
124
- session = null;
125
- active = false;
126
- reason = "disabled";
127
- lastMessage;
128
- lastPoint = null;
129
- async initialize(page) {
130
- this.page = page;
131
- if (page.isClosed()) {
132
- this.markInactive("page_closed");
133
- 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);
134
28
  }
135
- await this.createSession();
29
+ return this.runtime.open(normalized);
136
30
  }
137
- isActive() {
138
- return this.active;
31
+ async listPages(input = {}) {
32
+ return this.runtime.listPages(input);
139
33
  }
140
- status() {
141
- return {
142
- enabled: true,
143
- active: this.active,
144
- reason: this.reason ? this.lastMessage ? `${this.reason}: ${this.lastMessage}` : this.reason : void 0
145
- };
34
+ async newPage(input = {}) {
35
+ return this.runtime.newPage(input);
146
36
  }
147
- async move(point, style) {
148
- await this.sendWithRecovery(async (session) => {
149
- await session.send("Overlay.highlightQuad", {
150
- quad: buildCursorQuad(point, style.size),
151
- color: toProtocolRgba(style.fillColor),
152
- outlineColor: toProtocolRgba(style.outlineColor)
153
- });
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 }
154
80
  });
155
- this.lastPoint = point;
156
81
  }
157
- async pulse(point, style) {
158
- const pulseSize = style.size * style.pulseScale;
159
- const pulseFill = {
160
- ...style.fillColor,
161
- a: Math.min(1, style.fillColor.a * 0.14)
162
- };
163
- const pulseOutline = {
164
- ...style.haloColor,
165
- a: Math.min(1, style.haloColor.a * 0.9)
166
- };
167
- await this.sendWithRecovery(async (session) => {
168
- await session.send("Overlay.highlightQuad", {
169
- quad: buildCursorQuad(point, pulseSize),
170
- color: toProtocolRgba(pulseFill),
171
- outlineColor: toProtocolRgba(pulseOutline)
172
- });
82
+ async scroll(input) {
83
+ const normalized = normalizeTargetOptions(input);
84
+ return this.runtime.scroll({
85
+ ...normalized,
86
+ direction: input.direction,
87
+ amount: input.amount
173
88
  });
174
- await sleep(PULSE_DELAY_MS);
175
- await this.move(point, style);
176
- }
177
- async clear() {
178
- if (!this.session) return;
179
- try {
180
- await this.session.send("Overlay.hideHighlight");
181
- } catch {
182
- this.markInactive("cdp_detached");
183
- }
184
89
  }
185
- async dispose() {
186
- await this.cleanupSession();
187
- this.active = false;
188
- this.reason = "disabled";
189
- this.lastMessage = void 0;
190
- this.lastPoint = null;
191
- this.page = null;
192
- }
193
- async sendWithRecovery(operation) {
194
- if (!this.active || !this.session) return;
195
- try {
196
- await operation(this.session);
197
- } catch (error) {
198
- const message = error instanceof Error ? error.message : String(error);
199
- this.lastMessage = message;
200
- if (!isRecoverableProtocolError(message) || !this.page) {
201
- this.markInactive("renderer_error", message);
202
- 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];
203
108
  }
204
- await this.createSession();
205
- if (!this.active || !this.session) {
206
- 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;
207
138
  }
208
- try {
209
- await operation(this.session);
210
- } catch (retryError) {
211
- const retryMessage = retryError instanceof Error ? retryError.message : String(retryError);
212
- this.markInactive("renderer_error", retryMessage);
139
+ if (Date.now() >= timeoutAt) {
140
+ throw new Error("waitForPage timed out");
213
141
  }
142
+ await delay(pollIntervalMs);
214
143
  }
215
144
  }
216
- async createSession() {
217
- if (!this.page || this.page.isClosed()) {
218
- 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();
219
283
  return;
220
284
  }
221
- await this.cleanupSession();
222
- try {
223
- const session = await this.page.context().newCDPSession(this.page);
224
- await session.send("DOM.enable");
225
- await session.send("Overlay.enable");
226
- this.session = session;
227
- this.active = true;
228
- this.reason = void 0;
229
- this.lastMessage = void 0;
230
- } catch (error) {
231
- const message = error instanceof Error ? error.message : String(error);
232
- this.markInactive(inferSetupReason(message), message);
233
- await this.cleanupSession();
285
+ if (isDisconnectableRuntime(this.runtime)) {
286
+ await this.runtime.disconnect();
234
287
  }
235
288
  }
236
- async cleanupSession() {
237
- const session = this.session;
238
- this.session = null;
239
- if (!session) return;
240
- try {
241
- await session.detach();
242
- } catch {
243
- }
289
+ static fromRuntime(runtime, ownership) {
290
+ const instance = Object.create(_Opensteer.prototype);
291
+ instance.runtime = runtime;
292
+ instance.ownership = ownership;
293
+ return instance;
244
294
  }
245
- markInactive(reason, message) {
246
- this.active = false;
247
- this.reason = reason;
248
- 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.`);
249
300
  }
250
301
  };
251
- function buildCursorQuad(point, size) {
252
- const x = point.x;
253
- const y = point.y;
254
- return [
255
- // Point 0: Tip (the hotspot)
256
- roundPointValue(x),
257
- roundPointValue(y),
258
- // Point 1: Right shoulder — extends right and down
259
- roundPointValue(x + size * 0.45),
260
- roundPointValue(y + size * 0.78),
261
- // Point 2: Tail — bottom of the cursor shaft
262
- roundPointValue(x + size * 0.12),
263
- roundPointValue(y + size * 1.3),
264
- // Point 3: Left edge — stays close to the shaft
265
- roundPointValue(x - size * 0.04),
266
- roundPointValue(y + size * 0.62)
267
- ];
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
+ }
268
308
  }
269
- function inferSetupReason(message) {
270
- const lowered = message.toLowerCase();
271
- if (lowered.includes("not supported") || lowered.includes("only supported") || lowered.includes("unknown command")) {
272
- 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
+ };
273
337
  }
274
- 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
+ };
275
348
  }
276
- function isRecoverableProtocolError(message) {
277
- const lowered = message.toLowerCase();
278
- 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));
279
351
  }
280
- 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
+ }
281
385
  return {
282
- r: clampColor(color.r),
283
- g: clampColor(color.g),
284
- b: clampColor(color.b),
285
- a: clampAlpha(color.a)
386
+ points,
387
+ durationMs
286
388
  };
287
389
  }
288
- function clampColor(value) {
289
- 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
+ });
290
399
  }
291
- function clampAlpha(value) {
292
- const normalized = Number.isFinite(value) ? value : 1;
293
- 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
+ };
294
406
  }
295
- function roundPointValue(value) {
296
- return Math.round(value * 100) / 100;
407
+ function easeInOutCubic(t) {
408
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
297
409
  }
298
- function sleep(ms) {
299
- 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);
300
420
  }
301
- export {
302
- ActionWsClient,
303
- BrowserPool,
304
- BrowserProfileClient,
305
- CdpOverlayCursorRenderer,
306
- CloudCdpClient,
307
- CloudSessionClient,
308
- CounterResolutionError,
309
- CursorController,
310
- ElementPathError,
311
- LocalSelectorStorage,
312
- OPENSTEER_HIDDEN_ATTR,
313
- OPENSTEER_INTERACTIVE_ATTR,
314
- OPENSTEER_SCROLLABLE_ATTR,
315
- OS_BOUNDARY_ATTR,
316
- OS_IFRAME_BOUNDARY_TAG,
317
- OS_NODE_ID_ATTR,
318
- OS_SHADOW_BOUNDARY_TAG,
319
- OS_UNAVAILABLE_ATTR,
320
- Opensteer,
321
- OpensteerActionError,
322
- OpensteerAgentActionError,
323
- OpensteerAgentApiError,
324
- OpensteerAgentBusyError,
325
- OpensteerAgentConfigError,
326
- OpensteerAgentError,
327
- OpensteerAgentExecutionError,
328
- OpensteerAgentProviderError,
329
- OpensteerCloudError,
330
- OpensteerCuaAgentHandler,
331
- SvgCursorRenderer,
332
- buildArrayFieldPathCandidates,
333
- buildElementPathFromHandle,
334
- buildElementPathFromSelector,
335
- buildPathSelectorHint,
336
- cleanForAction,
337
- cleanForClickable,
338
- cleanForExtraction,
339
- cleanForFull,
340
- cleanForScrollable,
341
- clearCookies,
342
- clearPersistentProfileSingletons,
343
- cloneElementPath,
344
- closeTab,
345
- cloudActionMethods,
346
- cloudErrorCodes,
347
- cloudNotLaunchedError,
348
- cloudSessionContractVersion,
349
- cloudSessionSourceTypes,
350
- cloudSessionStatuses,
351
- cloudUnsupportedMethodError,
352
- collectLocalSelectorCacheEntries,
353
- countArrayItemsWithPath,
354
- createCuaClient,
355
- createEmptyRegistry,
356
- createExtractCallback,
357
- createIsolatedRuntimeProfile,
358
- createResolveCallback,
359
- createTab,
360
- detectChromePaths,
361
- expandHome,
362
- exportCookies,
363
- extractArrayRowsWithPaths,
364
- extractArrayWithPaths,
365
- extractWithPaths,
366
- getCookies,
367
- getElementAttributes,
368
- getElementBoundingBox,
369
- getElementText,
370
- getElementValue,
371
- getModelProvider,
372
- getOrCreatePersistentProfile,
373
- getPageHtml,
374
- getPageTitle,
375
- importCookies,
376
- isCloudActionMethod,
377
- isCloudErrorCode,
378
- isCloudSessionSourceType,
379
- isCloudSessionStatus,
380
- listLocalChromeProfiles,
381
- listTabs,
382
- markInteractiveElements,
383
- normalizeNamespace,
384
- performClick,
385
- performFileUpload,
386
- performHover,
387
- performInput,
388
- performScroll,
389
- performSelect,
390
- persistIsolatedRuntimeProfile,
391
- planSnappyCursorMotion,
392
- prepareSnapshot,
393
- pressKey,
394
- queryAllByElementPath,
395
- resolveAgentConfig,
396
- resolveCounterElement,
397
- resolveCountersBatch,
398
- resolveElementPath,
399
- resolveNamespaceDir,
400
- sanitizeElementPath,
401
- serializePageHTML,
402
- setCookie,
403
- switchTab,
404
- typeText,
405
- waitForVisualStability
406
- };
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