@aria-cli/tools 1.0.9 → 1.0.11
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.
- package/package.json +9 -5
- package/src/__tests__/web-fetch-download.test.ts +0 -433
- package/src/__tests__/web-tools.test.ts +0 -619
- package/src/ask-user-interaction.ts +0 -33
- package/src/cache/web-cache.ts +0 -110
- package/src/definitions/arion.ts +0 -118
- package/src/definitions/browser/browser.ts +0 -502
- package/src/definitions/browser/index.ts +0 -5
- package/src/definitions/browser/pw-downloads.ts +0 -142
- package/src/definitions/browser/pw-interactions.ts +0 -282
- package/src/definitions/browser/pw-responses.ts +0 -98
- package/src/definitions/browser/pw-session.ts +0 -405
- package/src/definitions/browser/pw-shared.ts +0 -85
- package/src/definitions/browser/pw-snapshot.ts +0 -383
- package/src/definitions/browser/pw-state.ts +0 -101
- package/src/definitions/browser/types.ts +0 -203
- package/src/definitions/code-intelligence.ts +0 -526
- package/src/definitions/core.ts +0 -118
- package/src/definitions/delegation.ts +0 -567
- package/src/definitions/deploy.ts +0 -73
- package/src/definitions/filesystem.ts +0 -217
- package/src/definitions/frg.ts +0 -67
- package/src/definitions/index.ts +0 -28
- package/src/definitions/memory.ts +0 -150
- package/src/definitions/messaging.ts +0 -734
- package/src/definitions/meta.ts +0 -392
- package/src/definitions/network.ts +0 -179
- package/src/definitions/outlook.ts +0 -318
- package/src/definitions/patch/apply-patch.ts +0 -235
- package/src/definitions/patch/fuzzy-match.ts +0 -217
- package/src/definitions/patch/index.ts +0 -1
- package/src/definitions/patch/patch-parser.ts +0 -297
- package/src/definitions/patch/sandbox-paths.ts +0 -129
- package/src/definitions/process/index.ts +0 -5
- package/src/definitions/process/process-registry.ts +0 -303
- package/src/definitions/process/process.ts +0 -456
- package/src/definitions/process/pty-keys.ts +0 -298
- package/src/definitions/process/session-slug.ts +0 -147
- package/src/definitions/quip.ts +0 -225
- package/src/definitions/search.ts +0 -67
- package/src/definitions/session-history.ts +0 -79
- package/src/definitions/shell.ts +0 -202
- package/src/definitions/slack.ts +0 -211
- package/src/definitions/web.ts +0 -119
- package/src/executors/apply-patch.ts +0 -1035
- package/src/executors/arion.ts +0 -199
- package/src/executors/code-intelligence.ts +0 -1179
- package/src/executors/deploy.ts +0 -1066
- package/src/executors/filesystem.ts +0 -1428
- package/src/executors/frg-freshness.ts +0 -743
- package/src/executors/frg.ts +0 -394
- package/src/executors/index.ts +0 -280
- package/src/executors/learning-meta.ts +0 -1367
- package/src/executors/lsp-client.ts +0 -355
- package/src/executors/memory.ts +0 -978
- package/src/executors/meta.ts +0 -293
- package/src/executors/process-registry.ts +0 -570
- package/src/executors/pty-session-store.ts +0 -43
- package/src/executors/pty.ts +0 -342
- package/src/executors/restart.ts +0 -133
- package/src/executors/search-freshness.ts +0 -249
- package/src/executors/search-types.ts +0 -98
- package/src/executors/search.ts +0 -89
- package/src/executors/self-diagnose.ts +0 -552
- package/src/executors/session-history.ts +0 -435
- package/src/executors/shell-safety.ts +0 -519
- package/src/executors/shell.ts +0 -1243
- package/src/executors/utils.ts +0 -40
- package/src/executors/web.ts +0 -786
- package/src/extraction/content-extraction.ts +0 -281
- package/src/extraction/index.ts +0 -5
- package/src/headless-control-contract.ts +0 -1149
- package/src/index.ts +0 -788
- package/src/local-control-http-auth.ts +0 -2
- package/src/mcp/client.ts +0 -218
- package/src/mcp/connection.ts +0 -568
- package/src/mcp/index.ts +0 -11
- package/src/mcp/jsonrpc.ts +0 -195
- package/src/mcp/types.ts +0 -199
- package/src/network-control-adapter.ts +0 -88
- package/src/network-runtime/address-types.ts +0 -218
- package/src/network-runtime/db-owner-fencing.ts +0 -91
- package/src/network-runtime/delivery-receipts.ts +0 -372
- package/src/network-runtime/direct-endpoint-authority.ts +0 -35
- package/src/network-runtime/index.ts +0 -316
- package/src/network-runtime/local-control-contract.ts +0 -784
- package/src/network-runtime/node-store-contract.ts +0 -46
- package/src/network-runtime/pair-route-contract.ts +0 -97
- package/src/network-runtime/peer-capabilities.ts +0 -48
- package/src/network-runtime/peer-principal-ref.ts +0 -20
- package/src/network-runtime/peer-state-machine.ts +0 -160
- package/src/network-runtime/protocol-schemas.ts +0 -265
- package/src/network-runtime/runtime-bootstrap-contract.ts +0 -83
- package/src/outlook/desktop-session.ts +0 -409
- package/src/policy.ts +0 -171
- package/src/providers/brave.ts +0 -80
- package/src/providers/duckduckgo.ts +0 -199
- package/src/providers/exa.ts +0 -85
- package/src/providers/firecrawl.ts +0 -77
- package/src/providers/index.ts +0 -8
- package/src/providers/jina.ts +0 -70
- package/src/providers/router.ts +0 -121
- package/src/providers/search-provider.ts +0 -74
- package/src/providers/tavily.ts +0 -74
- package/src/quip/desktop-session.ts +0 -435
- package/src/registry/index.ts +0 -1
- package/src/registry/registry.ts +0 -905
- package/src/runtime-socket-local-control-client.ts +0 -632
- package/src/security/dns-normalization.ts +0 -34
- package/src/security/dns-pinning.ts +0 -138
- package/src/security/external-content.ts +0 -129
- package/src/security/ssrf.ts +0 -207
- package/src/slack/desktop-session.ts +0 -493
- package/src/tool-factory.ts +0 -91
- package/src/types.ts +0 -1341
- package/src/utils/retry.ts +0 -163
- package/src/utils/safe-parse-json.ts +0 -176
- package/src/utils/url.ts +0 -20
- package/tests/benchmarks/registry.bench.ts +0 -57
- package/tests/cache/web-cache.test.ts +0 -147
- package/tests/critical-integration.test.ts +0 -1465
- package/tests/definitions/apply-patch.test.ts +0 -586
- package/tests/definitions/browser.test.ts +0 -495
- package/tests/definitions/delegation-pause-resume.test.ts +0 -758
- package/tests/definitions/execution.test.ts +0 -671
- package/tests/definitions/messaging-inbox-scope.test.ts +0 -229
- package/tests/definitions/messaging.test.ts +0 -1468
- package/tests/definitions/outlook.test.ts +0 -30
- package/tests/definitions/process.test.ts +0 -469
- package/tests/definitions/slack.test.ts +0 -28
- package/tests/definitions/tool-inventory.test.ts +0 -218
- package/tests/e2e/delegation-quest-orchestration.e2e.test.ts +0 -433
- package/tests/e2e/memory-tool-discovery-contract.e2e.test.ts +0 -81
- package/tests/executors/apply-patch.test.ts +0 -538
- package/tests/executors/arion.test.ts +0 -309
- package/tests/executors/conversation-primitives.test.ts +0 -250
- package/tests/executors/deploy.test.ts +0 -746
- package/tests/executors/filesystem-tools.test.ts +0 -357
- package/tests/executors/filesystem.test.ts +0 -959
- package/tests/executors/frg-freshness.test.ts +0 -136
- package/tests/executors/frg-merge.test.ts +0 -70
- package/tests/executors/frg-session-content.test.ts +0 -40
- package/tests/executors/frg.test.ts +0 -56
- package/tests/executors/memory-bugfixes.test.ts +0 -257
- package/tests/executors/memory-real-memoria.integration.test.ts +0 -316
- package/tests/executors/memory.test.ts +0 -853
- package/tests/executors/meta-tools.test.ts +0 -411
- package/tests/executors/meta.test.ts +0 -683
- package/tests/executors/path-containment.test.ts +0 -51
- package/tests/executors/process-registry.test.ts +0 -505
- package/tests/executors/pty.test.ts +0 -664
- package/tests/executors/quest-security.test.ts +0 -249
- package/tests/executors/read-file-media.test.ts +0 -230
- package/tests/executors/recall-knowledge-schema.test.ts +0 -209
- package/tests/executors/recall-tags.test.ts +0 -278
- package/tests/executors/remember-null-safety.contract.test.ts +0 -41
- package/tests/executors/restart.test.ts +0 -67
- package/tests/executors/search-unified.test.ts +0 -381
- package/tests/executors/session-history.test.ts +0 -340
- package/tests/executors/session-transcript.test.ts +0 -561
- package/tests/executors/shell-abort.test.ts +0 -416
- package/tests/executors/shell-env-blocklist.test.ts +0 -648
- package/tests/executors/shell-env-process.test.ts +0 -245
- package/tests/executors/shell-process-registry.test.ts +0 -334
- package/tests/executors/shell-tools.test.ts +0 -393
- package/tests/executors/shell.test.ts +0 -690
- package/tests/executors/web-abort-vs-timeout.test.ts +0 -213
- package/tests/executors/web-integration.test.ts +0 -633
- package/tests/executors/web-symlink.test.ts +0 -18
- package/tests/executors/web.test.ts +0 -1400
- package/tests/executors/write-stdin.test.ts +0 -145
- package/tests/extraction/content-extraction.test.ts +0 -153
- package/tests/guards/tools-default-test-lane.integration.test.ts +0 -21
- package/tests/guards/tools-package-test-commands.e2e.test.ts +0 -43
- package/tests/guards/tools-test-lane-manifest.contract.test.ts +0 -76
- package/tests/guards/tools-vitest-workspace-alias.contract.test.ts +0 -63
- package/tests/helpers/async-waits.ts +0 -53
- package/tests/integration/headless-control-contract.integration.test.ts +0 -153
- package/tests/integration/memory-tool-schema-parity.integration.test.ts +0 -67
- package/tests/integration/meta-tools-round-trip.integration.test.ts +0 -506
- package/tests/integration/quest-round-trip.test.ts +0 -303
- package/tests/integration/registry-executor-flow.test.ts +0 -85
- package/tests/integration.test.ts +0 -177
- package/tests/loading-tier.test.ts +0 -126
- package/tests/mcp/client-reconnect.test.ts +0 -267
- package/tests/mcp/connection.test.ts +0 -846
- package/tests/mcp/injectable-logger.test.ts +0 -83
- package/tests/mcp/jsonrpc.test.ts +0 -109
- package/tests/mcp/lifecycle.test.ts +0 -879
- package/tests/network-runtime/address-types.contract.test.ts +0 -143
- package/tests/network-runtime/continuity-bind-schema.contract.test.ts +0 -203
- package/tests/network-runtime/local-control-contract.test.ts +0 -869
- package/tests/network-runtime/local-control-invite-token.contract.test.ts +0 -146
- package/tests/network-runtime/node-store-contract.test.ts +0 -11
- package/tests/network-runtime/pair-protocol-nodeid.contract.test.ts +0 -15
- package/tests/network-runtime/peer-state-machine.contract.test.ts +0 -148
- package/tests/network-runtime/protocol-schemas.contract.test.ts +0 -512
- package/tests/network-runtime/relay-pending-nodeid.contract.test.ts +0 -62
- package/tests/network-runtime/runtime-bootstrap-contract.test.ts +0 -227
- package/tests/network-runtime/runtime-socket-local-control-client.test.ts +0 -621
- package/tests/network-runtime/wait-for-message-script.test.ts +0 -288
- package/tests/parallel.test.ts +0 -71
- package/tests/policy.test.ts +0 -184
- package/tests/print-default-test-lane.ts +0 -14
- package/tests/print-test-lane-manifest.ts +0 -22
- package/tests/providers/brave.test.ts +0 -159
- package/tests/providers/duckduckgo.test.ts +0 -207
- package/tests/providers/exa.test.ts +0 -175
- package/tests/providers/firecrawl.test.ts +0 -168
- package/tests/providers/jina.test.ts +0 -144
- package/tests/providers/router.test.ts +0 -328
- package/tests/providers/tavily.test.ts +0 -165
- package/tests/registry/discovery.test.ts +0 -154
- package/tests/registry/injectable-logger.test.ts +0 -230
- package/tests/registry/input-validation.test.ts +0 -361
- package/tests/registry/interface-completeness.test.ts +0 -85
- package/tests/registry/mcp-integration.test.ts +0 -103
- package/tests/registry/mcp-read-only-hint.test.ts +0 -60
- package/tests/registry/memoria-discovery.test.ts +0 -390
- package/tests/registry/nested-validation.test.ts +0 -283
- package/tests/registry/pseudo-tool-filtering.test.ts +0 -258
- package/tests/registry/registration-lifecycle.test.ts +0 -133
- package/tests/registry-validation.test.ts +0 -424
- package/tests/registry.test.ts +0 -460
- package/tests/security/dns-pinning.test.ts +0 -162
- package/tests/security/external-content.test.ts +0 -144
- package/tests/security/ssrf.test.ts +0 -118
- package/tests/shell-safety-integration.test.ts +0 -32
- package/tests/shell-safety.test.ts +0 -365
- package/tests/slack/desktop-session.test.ts +0 -50
- package/tests/test-lane-manifest.ts +0 -440
- package/tests/test-utils.ts +0 -27
- package/tests/tool-factory.test.ts +0 -188
- package/tests/utils/retry.test.ts +0 -231
- package/tests/utils/url.test.ts +0 -63
- package/tsconfig.cjs.json +0 -24
- package/tsconfig.json +0 -12
- package/vitest.config.ts +0 -55
- package/vitest.e2e.config.ts +0 -24
- package/vitest.integration.config.ts +0 -24
- package/vitest.native.config.ts +0 -24
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
// Originally from OpenClaw (MIT License, Copyright 2025 Peter Steinberger)
|
|
2
|
-
// https://github.com/openclaw/openclaw
|
|
3
|
-
// Modified for ARIA — stripped OpenClaw runtime, rewired to ARIA Tool interface
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* ARIA Browser Tool — Playwright-based browser automation.
|
|
7
|
-
*
|
|
8
|
-
* Single tool with an `action` discriminator that dispatches to the
|
|
9
|
-
* appropriate Playwright handler. The LLM calls `browser` with an action
|
|
10
|
-
* object; each action maps to a specific capability.
|
|
11
|
-
*
|
|
12
|
-
* Playwright is loaded dynamically so ARIA works without it installed.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { JSONSchema7 } from "json-schema";
|
|
16
|
-
import type { Tool, ToolResult } from "../../types.js";
|
|
17
|
-
import type { BrowserAction, BrowserSession } from "./types.js";
|
|
18
|
-
import {
|
|
19
|
-
launchBrowser,
|
|
20
|
-
closeBrowser,
|
|
21
|
-
getSession,
|
|
22
|
-
getRefs,
|
|
23
|
-
setRefs,
|
|
24
|
-
getConsoleMessages,
|
|
25
|
-
getNetworkRequests,
|
|
26
|
-
getPageErrors,
|
|
27
|
-
listTabs,
|
|
28
|
-
newTab,
|
|
29
|
-
selectTab,
|
|
30
|
-
closeTab,
|
|
31
|
-
} from "./pw-session.js";
|
|
32
|
-
import { snapshotPage, navigatePage } from "./pw-snapshot.js";
|
|
33
|
-
import {
|
|
34
|
-
clickViaPlaywright,
|
|
35
|
-
hoverViaPlaywright,
|
|
36
|
-
dragViaPlaywright,
|
|
37
|
-
typeViaPlaywright,
|
|
38
|
-
selectOptionViaPlaywright,
|
|
39
|
-
pressKeyViaPlaywright,
|
|
40
|
-
evaluateViaPlaywright,
|
|
41
|
-
takeScreenshot,
|
|
42
|
-
scrollPage,
|
|
43
|
-
waitForCondition,
|
|
44
|
-
uploadFiles,
|
|
45
|
-
} from "./pw-interactions.js";
|
|
46
|
-
import { cookiesGet, cookiesSet, cookiesClear } from "./pw-state.js";
|
|
47
|
-
import {
|
|
48
|
-
filterConsoleMessages,
|
|
49
|
-
filterNetworkRequests,
|
|
50
|
-
formatConsoleMessages,
|
|
51
|
-
formatNetworkRequests,
|
|
52
|
-
formatPageErrors,
|
|
53
|
-
} from "./pw-responses.js";
|
|
54
|
-
|
|
55
|
-
// ── JSON Schema for the action parameter ──────────────────────────────
|
|
56
|
-
|
|
57
|
-
const browserParameterSchema: JSONSchema7 = {
|
|
58
|
-
type: "object",
|
|
59
|
-
properties: {
|
|
60
|
-
action: {
|
|
61
|
-
type: "string",
|
|
62
|
-
enum: [
|
|
63
|
-
"launch",
|
|
64
|
-
"close",
|
|
65
|
-
"navigate",
|
|
66
|
-
"snapshot",
|
|
67
|
-
"click",
|
|
68
|
-
"type",
|
|
69
|
-
"hover",
|
|
70
|
-
"drag",
|
|
71
|
-
"select_option",
|
|
72
|
-
"press_key",
|
|
73
|
-
"scroll",
|
|
74
|
-
"evaluate",
|
|
75
|
-
"screenshot",
|
|
76
|
-
"get_console",
|
|
77
|
-
"get_network",
|
|
78
|
-
"wait",
|
|
79
|
-
"tab_list",
|
|
80
|
-
"tab_new",
|
|
81
|
-
"tab_select",
|
|
82
|
-
"tab_close",
|
|
83
|
-
"cookies_get",
|
|
84
|
-
"cookies_set",
|
|
85
|
-
"cookies_clear",
|
|
86
|
-
"upload",
|
|
87
|
-
],
|
|
88
|
-
description:
|
|
89
|
-
"The browser action to perform. 'launch' is optional; actions auto-start a session when needed. Use 'snapshot' to read page content, refs like [e1] with 'click'/'type'.",
|
|
90
|
-
},
|
|
91
|
-
// launch
|
|
92
|
-
url: { type: "string", description: "URL to navigate to (for launch/navigate/tab_new)" },
|
|
93
|
-
headless: {
|
|
94
|
-
type: "boolean",
|
|
95
|
-
description: "Run browser without visible window (default: true)",
|
|
96
|
-
},
|
|
97
|
-
// snapshot
|
|
98
|
-
interactive: {
|
|
99
|
-
type: "boolean",
|
|
100
|
-
description: "Only show interactive elements in snapshot (buttons, links, inputs)",
|
|
101
|
-
},
|
|
102
|
-
// click/type/hover/drag/select_option/upload
|
|
103
|
-
ref: {
|
|
104
|
-
type: "string",
|
|
105
|
-
description: "Element ref from snapshot (e.g. 'e1', 'e5')",
|
|
106
|
-
},
|
|
107
|
-
text: { type: "string", description: "Text to type (for 'type' action)" },
|
|
108
|
-
submit: {
|
|
109
|
-
type: "boolean",
|
|
110
|
-
description: "Press Enter after typing (for 'type' action)",
|
|
111
|
-
},
|
|
112
|
-
slowly: {
|
|
113
|
-
type: "boolean",
|
|
114
|
-
description: "Type character by character instead of filling (for 'type' action)",
|
|
115
|
-
},
|
|
116
|
-
button: {
|
|
117
|
-
type: "string",
|
|
118
|
-
enum: ["left", "right", "middle"],
|
|
119
|
-
description: "Mouse button (for 'click' action)",
|
|
120
|
-
},
|
|
121
|
-
modifiers: {
|
|
122
|
-
type: "array",
|
|
123
|
-
items: { type: "string" },
|
|
124
|
-
description: "Keyboard modifiers (for 'click': Alt, Control, Meta, Shift)",
|
|
125
|
-
},
|
|
126
|
-
doubleClick: {
|
|
127
|
-
type: "boolean",
|
|
128
|
-
description: "Double-click instead of single click",
|
|
129
|
-
},
|
|
130
|
-
startRef: {
|
|
131
|
-
type: "string",
|
|
132
|
-
description: "Source element ref (for 'drag' action)",
|
|
133
|
-
},
|
|
134
|
-
endRef: {
|
|
135
|
-
type: "string",
|
|
136
|
-
description: "Target element ref (for 'drag' action)",
|
|
137
|
-
},
|
|
138
|
-
values: {
|
|
139
|
-
type: "array",
|
|
140
|
-
items: { type: "string" },
|
|
141
|
-
description: "Values to select (for 'select_option' action)",
|
|
142
|
-
},
|
|
143
|
-
// press_key
|
|
144
|
-
key: {
|
|
145
|
-
type: "string",
|
|
146
|
-
description: "Key to press (for 'press_key': Enter, Tab, Escape, ArrowDown, etc.)",
|
|
147
|
-
},
|
|
148
|
-
// scroll
|
|
149
|
-
direction: {
|
|
150
|
-
type: "string",
|
|
151
|
-
enum: ["up", "down"],
|
|
152
|
-
description: "Scroll direction",
|
|
153
|
-
},
|
|
154
|
-
amount: {
|
|
155
|
-
type: "number",
|
|
156
|
-
description: "Scroll amount in pixels (default: 500)",
|
|
157
|
-
},
|
|
158
|
-
// evaluate
|
|
159
|
-
script: {
|
|
160
|
-
type: "string",
|
|
161
|
-
description: "JavaScript to evaluate in browser context (for 'evaluate' action)",
|
|
162
|
-
},
|
|
163
|
-
// get_console
|
|
164
|
-
level: {
|
|
165
|
-
type: "string",
|
|
166
|
-
description: "Minimum console level filter (debug/info/warning/error)",
|
|
167
|
-
},
|
|
168
|
-
// get_network
|
|
169
|
-
filter: {
|
|
170
|
-
type: "string",
|
|
171
|
-
description: "URL substring filter for network requests",
|
|
172
|
-
},
|
|
173
|
-
// wait
|
|
174
|
-
selector: {
|
|
175
|
-
type: "string",
|
|
176
|
-
description: "CSS selector to wait for (for 'wait' action)",
|
|
177
|
-
},
|
|
178
|
-
timeout: {
|
|
179
|
-
type: "number",
|
|
180
|
-
description: "Timeout in milliseconds (for 'wait' action)",
|
|
181
|
-
},
|
|
182
|
-
// tab_select
|
|
183
|
-
index: {
|
|
184
|
-
type: "number",
|
|
185
|
-
description: "Tab index (for 'tab_select'/'tab_close')",
|
|
186
|
-
},
|
|
187
|
-
// cookies_set
|
|
188
|
-
cookies: {
|
|
189
|
-
type: "array",
|
|
190
|
-
items: {
|
|
191
|
-
type: "object",
|
|
192
|
-
properties: {
|
|
193
|
-
name: { type: "string" },
|
|
194
|
-
value: { type: "string" },
|
|
195
|
-
domain: { type: "string" },
|
|
196
|
-
path: { type: "string" },
|
|
197
|
-
},
|
|
198
|
-
required: ["name", "value", "domain"],
|
|
199
|
-
},
|
|
200
|
-
description: "Cookies to set (for 'cookies_set' action)",
|
|
201
|
-
},
|
|
202
|
-
// upload
|
|
203
|
-
paths: {
|
|
204
|
-
type: "array",
|
|
205
|
-
items: { type: "string" },
|
|
206
|
-
description: "File paths to upload (for 'upload' action)",
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
required: ["action"],
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
// ── Helpers ───────────────────────────────────────────────────────────
|
|
213
|
-
|
|
214
|
-
function ok(message: string, data?: unknown): ToolResult {
|
|
215
|
-
return { success: true, message, data };
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function fail(message: string): ToolResult {
|
|
219
|
-
return { success: false, message };
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async function requireSession(): Promise<BrowserSession> {
|
|
223
|
-
const session = getSession();
|
|
224
|
-
if (session) {
|
|
225
|
-
return session;
|
|
226
|
-
}
|
|
227
|
-
return launchBrowser();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// ── Action dispatcher ─────────────────────────────────────────────────
|
|
231
|
-
|
|
232
|
-
async function executeBrowserAction(input: unknown): Promise<ToolResult> {
|
|
233
|
-
const action = input as BrowserAction;
|
|
234
|
-
|
|
235
|
-
try {
|
|
236
|
-
switch (action.action) {
|
|
237
|
-
// ── Lifecycle ─────────────────────────────────────────────────
|
|
238
|
-
case "launch": {
|
|
239
|
-
const session = await launchBrowser({
|
|
240
|
-
headless: action.headless,
|
|
241
|
-
url: action.url,
|
|
242
|
-
});
|
|
243
|
-
const url = session.page.url();
|
|
244
|
-
return ok(
|
|
245
|
-
`Browser launched.${action.url ? ` Navigated to ${url}` : ""}\nUse 'snapshot' to see page content.`,
|
|
246
|
-
{ url },
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
case "close": {
|
|
250
|
-
await closeBrowser();
|
|
251
|
-
return ok("Browser closed.");
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// ── Navigation ────────────────────────────────────────────────
|
|
255
|
-
case "navigate": {
|
|
256
|
-
const session = await requireSession();
|
|
257
|
-
const result = await navigatePage(session.page, action.url);
|
|
258
|
-
setRefs({}); // Refs are stale after navigation
|
|
259
|
-
return ok(`Navigated to ${result.url}. Use 'snapshot' to see page content.`, result);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ── Snapshot ──────────────────────────────────────────────────
|
|
263
|
-
case "snapshot": {
|
|
264
|
-
const session = await requireSession();
|
|
265
|
-
const result = await snapshotPage(session.page, {
|
|
266
|
-
interactive: action.interactive,
|
|
267
|
-
});
|
|
268
|
-
setRefs(result.refs);
|
|
269
|
-
const header =
|
|
270
|
-
`Page: ${result.title}\nURL: ${result.url}\n` +
|
|
271
|
-
`Elements: ${result.stats.refs} total, ${result.stats.interactive} interactive\n\n`;
|
|
272
|
-
return ok(header + result.snapshot, {
|
|
273
|
-
url: result.url,
|
|
274
|
-
title: result.title,
|
|
275
|
-
stats: result.stats,
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// ── Click ─────────────────────────────────────────────────────
|
|
280
|
-
case "click": {
|
|
281
|
-
const session = await requireSession();
|
|
282
|
-
await clickViaPlaywright({
|
|
283
|
-
page: session.page,
|
|
284
|
-
refs: getRefs(),
|
|
285
|
-
ref: action.ref,
|
|
286
|
-
doubleClick: action.doubleClick,
|
|
287
|
-
button: action.button,
|
|
288
|
-
modifiers: action.modifiers,
|
|
289
|
-
});
|
|
290
|
-
return ok(`Clicked ${action.ref}. Use 'snapshot' to see updated page.`);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// ── Type ──────────────────────────────────────────────────────
|
|
294
|
-
case "type": {
|
|
295
|
-
const session = await requireSession();
|
|
296
|
-
await typeViaPlaywright({
|
|
297
|
-
page: session.page,
|
|
298
|
-
refs: getRefs(),
|
|
299
|
-
ref: action.ref,
|
|
300
|
-
text: action.text,
|
|
301
|
-
submit: action.submit,
|
|
302
|
-
slowly: action.slowly,
|
|
303
|
-
});
|
|
304
|
-
return ok(
|
|
305
|
-
`Typed "${action.text.length > 50 ? action.text.slice(0, 50) + "..." : action.text}" into ${action.ref}.${action.submit ? " Submitted with Enter." : ""}`,
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// ── Hover ─────────────────────────────────────────────────────
|
|
310
|
-
case "hover": {
|
|
311
|
-
const session = await requireSession();
|
|
312
|
-
await hoverViaPlaywright({
|
|
313
|
-
page: session.page,
|
|
314
|
-
refs: getRefs(),
|
|
315
|
-
ref: action.ref,
|
|
316
|
-
});
|
|
317
|
-
return ok(`Hovered over ${action.ref}.`);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// ── Drag ──────────────────────────────────────────────────────
|
|
321
|
-
case "drag": {
|
|
322
|
-
const session = await requireSession();
|
|
323
|
-
await dragViaPlaywright({
|
|
324
|
-
page: session.page,
|
|
325
|
-
refs: getRefs(),
|
|
326
|
-
startRef: action.startRef,
|
|
327
|
-
endRef: action.endRef,
|
|
328
|
-
});
|
|
329
|
-
return ok(`Dragged ${action.startRef} to ${action.endRef}.`);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// ── Select option ─────────────────────────────────────────────
|
|
333
|
-
case "select_option": {
|
|
334
|
-
const session = await requireSession();
|
|
335
|
-
await selectOptionViaPlaywright({
|
|
336
|
-
page: session.page,
|
|
337
|
-
refs: getRefs(),
|
|
338
|
-
ref: action.ref,
|
|
339
|
-
values: action.values,
|
|
340
|
-
});
|
|
341
|
-
return ok(`Selected [${action.values.join(", ")}] in ${action.ref}.`);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// ── Key press ─────────────────────────────────────────────────
|
|
345
|
-
case "press_key": {
|
|
346
|
-
const session = await requireSession();
|
|
347
|
-
await pressKeyViaPlaywright({
|
|
348
|
-
page: session.page,
|
|
349
|
-
key: action.key,
|
|
350
|
-
});
|
|
351
|
-
return ok(`Pressed key: ${action.key}`);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// ── Scroll ────────────────────────────────────────────────────
|
|
355
|
-
case "scroll": {
|
|
356
|
-
const session = await requireSession();
|
|
357
|
-
await scrollPage({
|
|
358
|
-
page: session.page,
|
|
359
|
-
direction: action.direction,
|
|
360
|
-
amount: action.amount,
|
|
361
|
-
});
|
|
362
|
-
return ok(
|
|
363
|
-
`Scrolled ${action.direction} ${action.amount ?? 500}px. Use 'snapshot' to see updated content.`,
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// ── Evaluate ──────────────────────────────────────────────────
|
|
368
|
-
case "evaluate": {
|
|
369
|
-
const session = await requireSession();
|
|
370
|
-
const result = await evaluateViaPlaywright({
|
|
371
|
-
page: session.page,
|
|
372
|
-
script: action.script,
|
|
373
|
-
});
|
|
374
|
-
const output =
|
|
375
|
-
result === undefined
|
|
376
|
-
? "undefined"
|
|
377
|
-
: typeof result === "string"
|
|
378
|
-
? result
|
|
379
|
-
: JSON.stringify(result, null, 2);
|
|
380
|
-
return ok(output, { result });
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// ── Screenshot ────────────────────────────────────────────────
|
|
384
|
-
case "screenshot": {
|
|
385
|
-
const session = await requireSession();
|
|
386
|
-
const buffer = await takeScreenshot({ page: session.page });
|
|
387
|
-
const base64 = buffer.toString("base64");
|
|
388
|
-
return ok(`Screenshot taken (${buffer.length} bytes, base64-encoded).`, {
|
|
389
|
-
base64,
|
|
390
|
-
mimeType: "image/png",
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// ── Console ───────────────────────────────────────────────────
|
|
395
|
-
case "get_console": {
|
|
396
|
-
await requireSession();
|
|
397
|
-
const messages = filterConsoleMessages(getConsoleMessages(), action.level);
|
|
398
|
-
return ok(formatConsoleMessages(messages), { count: messages.length });
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// ── Network ───────────────────────────────────────────────────
|
|
402
|
-
case "get_network": {
|
|
403
|
-
await requireSession();
|
|
404
|
-
const requests = filterNetworkRequests(getNetworkRequests(), action.filter);
|
|
405
|
-
return ok(formatNetworkRequests(requests), { count: requests.length });
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// ── Wait ──────────────────────────────────────────────────────
|
|
409
|
-
case "wait": {
|
|
410
|
-
const session = await requireSession();
|
|
411
|
-
await waitForCondition({
|
|
412
|
-
page: session.page,
|
|
413
|
-
selector: action.selector,
|
|
414
|
-
text: action.text,
|
|
415
|
-
timeout: action.timeout,
|
|
416
|
-
});
|
|
417
|
-
return ok("Wait condition satisfied. Use 'snapshot' to see current page.");
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// ── Tab management ────────────────────────────────────────────
|
|
421
|
-
case "tab_list": {
|
|
422
|
-
const tabs = listTabs();
|
|
423
|
-
const desc = tabs
|
|
424
|
-
.map((t) => `[${t.index}]${t.active ? " (active)" : ""} ${t.url}`)
|
|
425
|
-
.join("\n");
|
|
426
|
-
return ok(desc || "No tabs open.", { tabs });
|
|
427
|
-
}
|
|
428
|
-
case "tab_new": {
|
|
429
|
-
const result = await newTab(action.url);
|
|
430
|
-
return ok(`Opened new tab [${result.index}]: ${result.url}`, result);
|
|
431
|
-
}
|
|
432
|
-
case "tab_select": {
|
|
433
|
-
await requireSession();
|
|
434
|
-
const result = await selectTab(action.index);
|
|
435
|
-
return ok(`Switched to tab ${action.index}: ${result.url}`, result);
|
|
436
|
-
}
|
|
437
|
-
case "tab_close": {
|
|
438
|
-
await closeTab(action.index);
|
|
439
|
-
return ok(`Tab closed.${action.index !== undefined ? ` (index ${action.index})` : ""}`);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// ── Cookies ───────────────────────────────────────────────────
|
|
443
|
-
case "cookies_get": {
|
|
444
|
-
const session = await requireSession();
|
|
445
|
-
const result = await cookiesGet(session.context);
|
|
446
|
-
const desc = result.cookies.length
|
|
447
|
-
? result.cookies.map((c) => `${c.name}=${c.value} (${c.domain})`).join("\n")
|
|
448
|
-
: "No cookies.";
|
|
449
|
-
return ok(desc, result);
|
|
450
|
-
}
|
|
451
|
-
case "cookies_set": {
|
|
452
|
-
const session = await requireSession();
|
|
453
|
-
await cookiesSet(session.context, action.cookies);
|
|
454
|
-
return ok(`Set ${action.cookies.length} cookie(s).`);
|
|
455
|
-
}
|
|
456
|
-
case "cookies_clear": {
|
|
457
|
-
const session = await requireSession();
|
|
458
|
-
await cookiesClear(session.context);
|
|
459
|
-
return ok("All cookies cleared.");
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// ── Upload ────────────────────────────────────────────────────
|
|
463
|
-
case "upload": {
|
|
464
|
-
const session = await requireSession();
|
|
465
|
-
await uploadFiles({
|
|
466
|
-
page: session.page,
|
|
467
|
-
refs: getRefs(),
|
|
468
|
-
ref: action.ref,
|
|
469
|
-
paths: action.paths,
|
|
470
|
-
});
|
|
471
|
-
return ok(`Uploaded ${action.paths.length} file(s) to ${action.ref}.`);
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
default: {
|
|
475
|
-
const exhaustive: never = action;
|
|
476
|
-
return fail(`Unknown browser action: ${(exhaustive as { action: string }).action}`);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
} catch (err) {
|
|
480
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
481
|
-
return fail(message);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// ── Tool definition ───────────────────────────────────────────────────
|
|
486
|
-
|
|
487
|
-
export const browserTool: Tool = {
|
|
488
|
-
name: "browser",
|
|
489
|
-
description:
|
|
490
|
-
"Control a web browser via Playwright. Supports navigation, clicking, typing, taking snapshots of page content, and more. " +
|
|
491
|
-
"Actions auto-start a browser session; use 'launch' only when you want explicit startup control. Use 'snapshot' to see the current page state as an accessibility tree with element refs like [e1], [e2]. " +
|
|
492
|
-
"Use those refs with 'click', 'type', 'hover', etc. to interact with elements. " +
|
|
493
|
-
"Use 'evaluate' to run JavaScript in the page context. Use 'screenshot' to capture the page visually.",
|
|
494
|
-
category: "web",
|
|
495
|
-
parameters: browserParameterSchema,
|
|
496
|
-
riskLevel: "moderate",
|
|
497
|
-
isReadOnly: false,
|
|
498
|
-
loadingTier: "always",
|
|
499
|
-
async execute(input: unknown, _context) {
|
|
500
|
-
return executeBrowserAction(input);
|
|
501
|
-
},
|
|
502
|
-
};
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// Originally from OpenClaw (MIT License, Copyright 2025 Peter Steinberger)
|
|
2
|
-
// https://github.com/openclaw/openclaw
|
|
3
|
-
// Modified for ARIA — stripped OpenClaw runtime, rewired to ARIA Tool interface
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* File upload and download handling.
|
|
7
|
-
* Ported from OpenClaw's pw-tools-core.downloads.ts.
|
|
8
|
-
*
|
|
9
|
-
* Note: Upload is handled in pw-interactions.ts via setInputFiles.
|
|
10
|
-
* This module provides download capture via page "download" event.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { tmpdir } from "node:os";
|
|
14
|
-
import { join, dirname, resolve, basename } from "node:path";
|
|
15
|
-
import { mkdir } from "node:fs/promises";
|
|
16
|
-
import { randomUUID } from "node:crypto";
|
|
17
|
-
import type { PwPage } from "./types.js";
|
|
18
|
-
import { normalizeTimeoutMs } from "./pw-shared.js";
|
|
19
|
-
|
|
20
|
-
// ── Filename sanitization ─────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
function sanitizeDownloadFileName(fileName: string): string {
|
|
23
|
-
const trimmed = String(fileName ?? "").trim();
|
|
24
|
-
if (!trimmed) {
|
|
25
|
-
return "download.bin";
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Force a basename so path separators/traversal can't escape the downloads dir.
|
|
29
|
-
let base = basename(trimmed);
|
|
30
|
-
let cleaned = "";
|
|
31
|
-
for (let i = 0; i < base.length; i++) {
|
|
32
|
-
const code = base.charCodeAt(i);
|
|
33
|
-
if (code < 0x20 || code === 0x7f) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
cleaned += base[i];
|
|
37
|
-
}
|
|
38
|
-
base = cleaned.trim();
|
|
39
|
-
|
|
40
|
-
if (!base || base === "." || base === "..") {
|
|
41
|
-
return "download.bin";
|
|
42
|
-
}
|
|
43
|
-
if (base.length > 200) {
|
|
44
|
-
base = base.slice(0, 200);
|
|
45
|
-
}
|
|
46
|
-
return base;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function buildTempDownloadPath(fileName: string): string {
|
|
50
|
-
const id = randomUUID();
|
|
51
|
-
const safeName = sanitizeDownloadFileName(fileName);
|
|
52
|
-
return join(tmpdir(), "aria-downloads", `${id}-${safeName}`);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// ── Download waiter ───────────────────────────────────────────────────
|
|
56
|
-
|
|
57
|
-
function createPageDownloadWaiter(page: PwPage, timeoutMs: number) {
|
|
58
|
-
let done = false;
|
|
59
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
60
|
-
let handler: ((...args: unknown[]) => void) | undefined;
|
|
61
|
-
|
|
62
|
-
const cleanup = () => {
|
|
63
|
-
if (timer) {
|
|
64
|
-
clearTimeout(timer);
|
|
65
|
-
}
|
|
66
|
-
timer = undefined;
|
|
67
|
-
if (handler) {
|
|
68
|
-
page.off("download", handler);
|
|
69
|
-
handler = undefined;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const promise = new Promise<unknown>((resolveP, reject) => {
|
|
74
|
-
handler = (download: unknown) => {
|
|
75
|
-
if (done) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
done = true;
|
|
79
|
-
cleanup();
|
|
80
|
-
resolveP(download);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
page.on("download", handler);
|
|
84
|
-
timer = setTimeout(() => {
|
|
85
|
-
if (done) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
done = true;
|
|
89
|
-
cleanup();
|
|
90
|
-
reject(new Error("Timeout waiting for download"));
|
|
91
|
-
}, timeoutMs);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
promise,
|
|
96
|
-
cancel: () => {
|
|
97
|
-
if (done) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
done = true;
|
|
101
|
-
cleanup();
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// ── Public API ────────────────────────────────────────────────────────
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Wait for the next download event on the page and save the file.
|
|
110
|
-
*/
|
|
111
|
-
export async function waitForDownload(opts: {
|
|
112
|
-
page: PwPage;
|
|
113
|
-
path?: string;
|
|
114
|
-
timeoutMs?: number;
|
|
115
|
-
}): Promise<{
|
|
116
|
-
url: string;
|
|
117
|
-
suggestedFilename: string;
|
|
118
|
-
path: string;
|
|
119
|
-
}> {
|
|
120
|
-
const timeout = normalizeTimeoutMs(opts.timeoutMs, 120_000);
|
|
121
|
-
|
|
122
|
-
const waiter = createPageDownloadWaiter(opts.page, timeout);
|
|
123
|
-
try {
|
|
124
|
-
const download = (await waiter.promise) as {
|
|
125
|
-
url?: () => string;
|
|
126
|
-
suggestedFilename?: () => string;
|
|
127
|
-
saveAs?: (outPath: string) => Promise<void>;
|
|
128
|
-
};
|
|
129
|
-
const suggested = download.suggestedFilename?.() || "download.bin";
|
|
130
|
-
const outPath = opts.path?.trim() || buildTempDownloadPath(suggested);
|
|
131
|
-
await mkdir(dirname(outPath), { recursive: true });
|
|
132
|
-
await download.saveAs?.(outPath);
|
|
133
|
-
return {
|
|
134
|
-
url: download.url?.() || "",
|
|
135
|
-
suggestedFilename: suggested,
|
|
136
|
-
path: resolve(outPath),
|
|
137
|
-
};
|
|
138
|
-
} catch (err) {
|
|
139
|
-
waiter.cancel();
|
|
140
|
-
throw err;
|
|
141
|
-
}
|
|
142
|
-
}
|