orient-cli 0.2.1 → 0.3.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.
- package/dist/extensions/orient-playwright.d.ts +7 -0
- package/dist/extensions/orient-playwright.js +8 -0
- package/dist/extensions/orient-playwright.js.map +1 -0
- package/dist/extensions/orient-web-search.d.ts +5 -0
- package/dist/extensions/orient-web-search.js +6 -0
- package/dist/extensions/orient-web-search.js.map +1 -0
- package/dist/integrations/notebooklm/setup.d.ts +94 -0
- package/dist/integrations/notebooklm/setup.js +311 -0
- package/dist/integrations/notebooklm/setup.js.map +1 -0
- package/dist/integrations/playwright/bridge.d.ts +85 -0
- package/dist/integrations/playwright/bridge.js +225 -0
- package/dist/integrations/playwright/bridge.js.map +1 -0
- package/dist/integrations/playwright/playwright-extension.d.ts +22 -0
- package/dist/integrations/playwright/playwright-extension.js +209 -0
- package/dist/integrations/playwright/playwright-extension.js.map +1 -0
- package/dist/integrations/web-search/bridge.d.ts +79 -0
- package/dist/integrations/web-search/bridge.js +298 -0
- package/dist/integrations/web-search/bridge.js.map +1 -0
- package/dist/integrations/web-search/web-search-extension.d.ts +26 -0
- package/dist/integrations/web-search/web-search-extension.js +122 -0
- package/dist/integrations/web-search/web-search-extension.js.map +1 -0
- package/dist/orient/orient-extension.js +149 -1
- package/dist/orient/orient-extension.js.map +1 -1
- package/dist/package-paths.js +6 -1
- package/dist/package-paths.js.map +1 -1
- package/node_modules/@orient-cli/agent-core/package.json +2 -2
- package/node_modules/@orient-cli/ai/package.json +1 -1
- package/node_modules/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.js +2 -2
- package/node_modules/@orient-cli/coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@orient-cli/coding-agent/package.json +4 -4
- package/node_modules/@orient-cli/tui/package.json +1 -1
- package/node_modules/mime-db/HISTORY.md +541 -0
- package/node_modules/mime-db/LICENSE +23 -0
- package/node_modules/mime-db/README.md +109 -0
- package/node_modules/mime-db/db.json +9342 -0
- package/node_modules/mime-db/index.js +12 -0
- package/node_modules/mime-db/package.json +56 -0
- package/node_modules/mime-types/HISTORY.md +428 -0
- package/node_modules/mime-types/LICENSE +23 -0
- package/node_modules/mime-types/README.md +126 -0
- package/node_modules/mime-types/index.js +211 -0
- package/node_modules/mime-types/mimeScore.js +57 -0
- package/node_modules/mime-types/package.json +49 -0
- package/package.json +13 -6
- package/scripts/postinstall.mjs +235 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright bridge for ORIENT CLI
|
|
3
|
+
* =================================
|
|
4
|
+
*
|
|
5
|
+
* Thin subprocess wrapper around `playwright-cli` (the active
|
|
6
|
+
* microsoft/playwright-cli repo, published as `@playwright/cli`).
|
|
7
|
+
* ORIENT ships `@playwright/cli` as a default dependency so browser
|
|
8
|
+
* automation works out of the box — the same pattern Gemini CLI,
|
|
9
|
+
* OpenCode, and Droid use for their own browser tools.
|
|
10
|
+
*
|
|
11
|
+
* Why subprocess and not programmatic?
|
|
12
|
+
* - @playwright/cli maintains its own per-session browser state
|
|
13
|
+
* under `PLAYWRIGHT_CLI_SESSION=<name>`. Reusing that session
|
|
14
|
+
* machinery through the CLI is free; reimplementing it on top
|
|
15
|
+
* of the `playwright` library would duplicate work.
|
|
16
|
+
* - The agent can also invoke `playwright-cli` directly via the
|
|
17
|
+
* bash tool, so having our extension call the same binary keeps
|
|
18
|
+
* both entry points consistent (no drift between "ORIENT tool"
|
|
19
|
+
* and "bash playwright-cli").
|
|
20
|
+
* - Upgrading playwright-cli is a pure npm dependency bump; no
|
|
21
|
+
* extension code changes required.
|
|
22
|
+
*
|
|
23
|
+
* Chromium browser binaries are NOT shipped with this package —
|
|
24
|
+
* `playwright install chromium` has to be run once per machine
|
|
25
|
+
* (~170 MB download). The bridge detects when the binary is
|
|
26
|
+
* missing and returns a helpful error pointing at the install
|
|
27
|
+
* command. Users can pre-warm via `/orient.playwright.setup`.
|
|
28
|
+
*/
|
|
29
|
+
import { execFile, spawn } from "node:child_process";
|
|
30
|
+
import { existsSync } from "node:fs";
|
|
31
|
+
import { dirname, resolve } from "node:path";
|
|
32
|
+
import { fileURLToPath } from "node:url";
|
|
33
|
+
import { promisify } from "node:util";
|
|
34
|
+
const execFileAsync = promisify(execFile);
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the `playwright-cli` binary that ships inside this package's
|
|
37
|
+
* node_modules. When orient-cli is installed globally, npm places the
|
|
38
|
+
* playwright-cli entry at `<orient-cli>/node_modules/.bin/playwright-cli`.
|
|
39
|
+
* We find it via require.resolve of the `@playwright/cli` package.json,
|
|
40
|
+
* then walk up to the nearest `.bin`. Falling back to $PATH keeps
|
|
41
|
+
* workspace-dev runs working even when the binary isn't hoisted the
|
|
42
|
+
* same way a global install would hoist it.
|
|
43
|
+
*/
|
|
44
|
+
function resolvePlaywrightCliBinary() {
|
|
45
|
+
// import.meta.url → file:///.../dist/integrations/playwright/bridge.js
|
|
46
|
+
// Walk up to the orient package root, then look in node_modules/.bin.
|
|
47
|
+
try {
|
|
48
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
49
|
+
const candidates = [
|
|
50
|
+
resolve(here, "..", "..", "..", "..", "node_modules", ".bin", "playwright-cli"),
|
|
51
|
+
resolve(here, "..", "..", "..", "node_modules", ".bin", "playwright-cli"),
|
|
52
|
+
resolve(here, "..", "..", "node_modules", ".bin", "playwright-cli"),
|
|
53
|
+
];
|
|
54
|
+
for (const candidate of candidates) {
|
|
55
|
+
if (existsSync(candidate))
|
|
56
|
+
return candidate;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Fall through.
|
|
61
|
+
}
|
|
62
|
+
// Last resort: assume it's on PATH.
|
|
63
|
+
return "playwright-cli";
|
|
64
|
+
}
|
|
65
|
+
const PLAYWRIGHT_CLI = resolvePlaywrightCliBinary();
|
|
66
|
+
const DEFAULT_TIMEOUT = 60_000; // 60s — long enough for heavy pages
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Availability + setup
|
|
69
|
+
// ============================================================================
|
|
70
|
+
/**
|
|
71
|
+
* Check whether `playwright-cli` is resolvable and whether the
|
|
72
|
+
* Chromium browser binary has been installed. Chromium absence is
|
|
73
|
+
* treated as an expected first-run state, not an error.
|
|
74
|
+
*/
|
|
75
|
+
export async function checkPlaywrightAvailability(sessionName = "orient") {
|
|
76
|
+
let cliInstalled = false;
|
|
77
|
+
try {
|
|
78
|
+
await execFileAsync(PLAYWRIGHT_CLI, ["--version"], { timeout: 10_000 });
|
|
79
|
+
cliInstalled = true;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
cliInstalled = false;
|
|
83
|
+
}
|
|
84
|
+
let chromiumInstalled = false;
|
|
85
|
+
if (cliInstalled) {
|
|
86
|
+
try {
|
|
87
|
+
// `playwright-cli list` works without an active session and
|
|
88
|
+
// doesn't require a browser binary. A failing invocation
|
|
89
|
+
// usually means the browser hasn't been downloaded yet.
|
|
90
|
+
await execFileAsync(PLAYWRIGHT_CLI, ["list"], {
|
|
91
|
+
timeout: 10_000,
|
|
92
|
+
env: { ...process.env, PLAYWRIGHT_CLI_SESSION: sessionName },
|
|
93
|
+
});
|
|
94
|
+
chromiumInstalled = true;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
chromiumInstalled = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { cliInstalled, chromiumInstalled, sessionName };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Run `npx playwright install chromium` to fetch the Chromium
|
|
104
|
+
* browser binary. Streams stdout / stderr via the onProgress
|
|
105
|
+
* callback so callers can surface the ~170 MB download in the TUI.
|
|
106
|
+
*/
|
|
107
|
+
export async function installChromium(onProgress) {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
// Use `npx` so we don't need playwright itself on PATH.
|
|
110
|
+
const proc = spawn("npx", ["--yes", "playwright", "install", "chromium"], {
|
|
111
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
112
|
+
});
|
|
113
|
+
let stderr = "";
|
|
114
|
+
proc.stdout.on("data", (chunk) => onProgress?.(chunk.toString()));
|
|
115
|
+
proc.stderr.on("data", (chunk) => {
|
|
116
|
+
stderr += chunk.toString();
|
|
117
|
+
onProgress?.(chunk.toString());
|
|
118
|
+
});
|
|
119
|
+
proc.on("error", reject);
|
|
120
|
+
proc.on("close", (code) => {
|
|
121
|
+
if (code === 0)
|
|
122
|
+
resolve();
|
|
123
|
+
else
|
|
124
|
+
reject(new Error(`playwright install chromium failed (exit ${code}): ${stderr.slice(0, 400)}`));
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Browser operations (thin wrappers — agent can also call playwright-cli directly)
|
|
130
|
+
// ============================================================================
|
|
131
|
+
function baseEnv(sessionName) {
|
|
132
|
+
return { ...process.env, PLAYWRIGHT_CLI_SESSION: sessionName };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Navigate the session's browser to a URL. Opens the page if no page
|
|
136
|
+
* is active for the session yet.
|
|
137
|
+
*/
|
|
138
|
+
export async function goto(url, sessionName = "orient") {
|
|
139
|
+
const { stdout } = await execFileAsync(PLAYWRIGHT_CLI, ["goto", url], {
|
|
140
|
+
timeout: DEFAULT_TIMEOUT,
|
|
141
|
+
env: baseEnv(sessionName),
|
|
142
|
+
});
|
|
143
|
+
return stdout.trim();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Take a snapshot of the current page. `playwright-cli snapshot`
|
|
147
|
+
* returns an accessibility-tree-style text representation optimized
|
|
148
|
+
* for LLM consumption (same pattern as Playwright MCP).
|
|
149
|
+
*/
|
|
150
|
+
export async function snapshot(sessionName = "orient") {
|
|
151
|
+
const { stdout } = await execFileAsync(PLAYWRIGHT_CLI, ["snapshot"], {
|
|
152
|
+
timeout: DEFAULT_TIMEOUT,
|
|
153
|
+
env: baseEnv(sessionName),
|
|
154
|
+
});
|
|
155
|
+
try {
|
|
156
|
+
const parsed = JSON.parse(stdout);
|
|
157
|
+
return {
|
|
158
|
+
url: parsed.url ?? "",
|
|
159
|
+
title: parsed.title ?? "",
|
|
160
|
+
text: parsed.text ?? parsed.snapshot ?? stdout,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { url: "", title: "", text: stdout };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Click an element matched by a Playwright selector (CSS, text, role,
|
|
169
|
+
* or one of playwright-cli's own locator shortcuts).
|
|
170
|
+
*/
|
|
171
|
+
export async function click(selector, sessionName = "orient") {
|
|
172
|
+
const { stdout } = await execFileAsync(PLAYWRIGHT_CLI, ["click", selector], {
|
|
173
|
+
timeout: DEFAULT_TIMEOUT,
|
|
174
|
+
env: baseEnv(sessionName),
|
|
175
|
+
});
|
|
176
|
+
return stdout.trim();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Fill a text input matched by `selector` with `value`.
|
|
180
|
+
*/
|
|
181
|
+
export async function fill(selector, value, sessionName = "orient") {
|
|
182
|
+
const { stdout } = await execFileAsync(PLAYWRIGHT_CLI, ["fill", selector, value], {
|
|
183
|
+
timeout: DEFAULT_TIMEOUT,
|
|
184
|
+
env: baseEnv(sessionName),
|
|
185
|
+
});
|
|
186
|
+
return stdout.trim();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Take a screenshot of the current page and save it to `outputPath`.
|
|
190
|
+
* Returns the full path of the saved file.
|
|
191
|
+
*/
|
|
192
|
+
export async function screenshot(outputPath, sessionName = "orient") {
|
|
193
|
+
await execFileAsync(PLAYWRIGHT_CLI, ["screenshot", outputPath], {
|
|
194
|
+
timeout: DEFAULT_TIMEOUT,
|
|
195
|
+
env: baseEnv(sessionName),
|
|
196
|
+
});
|
|
197
|
+
return outputPath;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Evaluate JavaScript against the current page. Used for ad-hoc
|
|
201
|
+
* DOM extraction the agent couldn't get from `snapshot`.
|
|
202
|
+
*/
|
|
203
|
+
export async function evaluate(expression, sessionName = "orient") {
|
|
204
|
+
const { stdout } = await execFileAsync(PLAYWRIGHT_CLI, ["eval", expression], {
|
|
205
|
+
timeout: DEFAULT_TIMEOUT,
|
|
206
|
+
env: baseEnv(sessionName),
|
|
207
|
+
});
|
|
208
|
+
return stdout.trim();
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Close the session's browser cleanly. Call this at end-of-packet so
|
|
212
|
+
* headless chromium processes don't linger.
|
|
213
|
+
*/
|
|
214
|
+
export async function close(sessionName = "orient") {
|
|
215
|
+
try {
|
|
216
|
+
await execFileAsync(PLAYWRIGHT_CLI, ["close"], {
|
|
217
|
+
timeout: 10_000,
|
|
218
|
+
env: baseEnv(sessionName),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Best-effort cleanup; ignore errors if already closed.
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../src/integrations/playwright/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright extension for ORIENT CLI
|
|
3
|
+
* ====================================
|
|
4
|
+
*
|
|
5
|
+
* Registers a compact set of browser-driving tools (goto, snapshot,
|
|
6
|
+
* click, fill, screenshot, eval, close) backed by the `playwright-cli`
|
|
7
|
+
* binary that ships as a default dependency of orient-cli.
|
|
8
|
+
*
|
|
9
|
+
* Shipping playwright-cli by default matches the pattern the user
|
|
10
|
+
* requested: browser automation should "just work" after
|
|
11
|
+
* `npm install -g orient-cli@latest` — no manual opt-in, no secondary
|
|
12
|
+
* install step (the chromium browser binary is fetched during the
|
|
13
|
+
* orient-cli postinstall script, ~170 MB one-time).
|
|
14
|
+
*
|
|
15
|
+
* The tools here are deliberately thin wrappers. The agent can drive
|
|
16
|
+
* far more of playwright-cli's surface via the bash tool — this
|
|
17
|
+
* extension just exposes the half-dozen highest-value operations as
|
|
18
|
+
* first-class LLM-callable tools so the model doesn't have to think
|
|
19
|
+
* about the subprocess layer for common flows.
|
|
20
|
+
*/
|
|
21
|
+
import type { ExtensionAPI } from "@orient-cli/coding-agent";
|
|
22
|
+
export default function playwrightExtension(pi: ExtensionAPI): Promise<void>;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright extension for ORIENT CLI
|
|
3
|
+
* ====================================
|
|
4
|
+
*
|
|
5
|
+
* Registers a compact set of browser-driving tools (goto, snapshot,
|
|
6
|
+
* click, fill, screenshot, eval, close) backed by the `playwright-cli`
|
|
7
|
+
* binary that ships as a default dependency of orient-cli.
|
|
8
|
+
*
|
|
9
|
+
* Shipping playwright-cli by default matches the pattern the user
|
|
10
|
+
* requested: browser automation should "just work" after
|
|
11
|
+
* `npm install -g orient-cli@latest` — no manual opt-in, no secondary
|
|
12
|
+
* install step (the chromium browser binary is fetched during the
|
|
13
|
+
* orient-cli postinstall script, ~170 MB one-time).
|
|
14
|
+
*
|
|
15
|
+
* The tools here are deliberately thin wrappers. The agent can drive
|
|
16
|
+
* far more of playwright-cli's surface via the bash tool — this
|
|
17
|
+
* extension just exposes the half-dozen highest-value operations as
|
|
18
|
+
* first-class LLM-callable tools so the model doesn't have to think
|
|
19
|
+
* about the subprocess layer for common flows.
|
|
20
|
+
*/
|
|
21
|
+
import { Type } from "@sinclair/typebox";
|
|
22
|
+
import { checkPlaywrightAvailability, click, close, evaluate, fill, goto, installChromium, screenshot, snapshot, } from "./bridge.js";
|
|
23
|
+
const DEFAULT_SESSION = "orient";
|
|
24
|
+
export default async function playwrightExtension(pi) {
|
|
25
|
+
const availability = await checkPlaywrightAvailability(DEFAULT_SESSION);
|
|
26
|
+
if (!availability.cliInstalled) {
|
|
27
|
+
pi.on("session_start", (_event, ctx) => {
|
|
28
|
+
ctx.ui.setStatus("playwright", "@playwright/cli missing — reinstall orient-cli or run `npm install -g @playwright/cli`");
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
pi.on("session_start", (_event, ctx) => {
|
|
33
|
+
if (availability.chromiumInstalled) {
|
|
34
|
+
ctx.ui.setStatus("playwright", "playwright-cli ready (chromium installed)");
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
ctx.ui.setStatus("playwright", "playwright-cli ready, chromium missing — run /orient.playwright.setup");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// ========================================================================
|
|
41
|
+
// Setup command
|
|
42
|
+
// ========================================================================
|
|
43
|
+
pi.registerCommand("orient.playwright.setup", {
|
|
44
|
+
description: "Install the Chromium browser binary that playwright-cli drives",
|
|
45
|
+
handler: async (_args, ctx) => {
|
|
46
|
+
ctx.ui.notify("Installing Chromium via `npx playwright install chromium` (~170 MB one-time download)…", "info");
|
|
47
|
+
try {
|
|
48
|
+
await installChromium((chunk) => {
|
|
49
|
+
// Stream periodic progress ticks into the chat so the user sees the download is alive.
|
|
50
|
+
const trimmed = chunk.trim();
|
|
51
|
+
if (trimmed.length > 0)
|
|
52
|
+
ctx.ui.notify(trimmed, "info");
|
|
53
|
+
});
|
|
54
|
+
ctx.ui.notify("✓ Chromium installed. Browser tools are ready.", "info");
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
ctx.ui.notify(`Chromium install failed: ${err.message}`, "error");
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
// ========================================================================
|
|
62
|
+
// Browser tools
|
|
63
|
+
// ========================================================================
|
|
64
|
+
pi.registerTool({
|
|
65
|
+
name: "playwright_goto",
|
|
66
|
+
label: "Browser Navigate",
|
|
67
|
+
description: "Navigate the shared orient browser session to a URL. Opens a Chromium window backed by playwright-cli if none is open yet.",
|
|
68
|
+
promptSnippet: "Open a URL in the orient browser session.",
|
|
69
|
+
parameters: Type.Object({
|
|
70
|
+
url: Type.String({ description: "Absolute URL to navigate to (https://...)" }),
|
|
71
|
+
}),
|
|
72
|
+
async execute(_toolCallId, params) {
|
|
73
|
+
try {
|
|
74
|
+
const out = await goto(params.url);
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: "text", text: `Navigated to ${params.url}\n${out}` }],
|
|
77
|
+
details: null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return {
|
|
82
|
+
content: [{ type: "text", text: `goto failed: ${err.message}` }],
|
|
83
|
+
details: null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
pi.registerTool({
|
|
89
|
+
name: "playwright_snapshot",
|
|
90
|
+
label: "Browser Snapshot",
|
|
91
|
+
description: "Take an accessibility-tree snapshot of the current page — the LLM-friendly text representation playwright-cli emits. Use this instead of raw HTML for understanding what's on the page.",
|
|
92
|
+
promptSnippet: "Snapshot the current browser page as accessibility-tree text.",
|
|
93
|
+
parameters: Type.Object({}),
|
|
94
|
+
async execute() {
|
|
95
|
+
try {
|
|
96
|
+
const snap = await snapshot();
|
|
97
|
+
const body = snap.url || snap.title
|
|
98
|
+
? `URL: ${snap.url}\nTitle: ${snap.title}\n\n${snap.text}`
|
|
99
|
+
: snap.text;
|
|
100
|
+
return {
|
|
101
|
+
content: [{ type: "text", text: body }],
|
|
102
|
+
details: null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
return {
|
|
107
|
+
content: [{ type: "text", text: `snapshot failed: ${err.message}` }],
|
|
108
|
+
details: null,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
pi.registerTool({
|
|
114
|
+
name: "playwright_click",
|
|
115
|
+
label: "Browser Click",
|
|
116
|
+
description: "Click an element on the current page. Accepts a Playwright selector (CSS, text=, role=, etc.).",
|
|
117
|
+
promptSnippet: "Click an element in the browser.",
|
|
118
|
+
parameters: Type.Object({
|
|
119
|
+
selector: Type.String({
|
|
120
|
+
description: "Playwright selector. Examples: 'button.submit', 'text=Sign in', 'role=link[name=Docs]'",
|
|
121
|
+
}),
|
|
122
|
+
}),
|
|
123
|
+
async execute(_toolCallId, params) {
|
|
124
|
+
try {
|
|
125
|
+
const out = await click(params.selector);
|
|
126
|
+
return { content: [{ type: "text", text: out || `clicked ${params.selector}` }], details: null };
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return { content: [{ type: "text", text: `click failed: ${err.message}` }], details: null };
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
pi.registerTool({
|
|
134
|
+
name: "playwright_fill",
|
|
135
|
+
label: "Browser Fill",
|
|
136
|
+
description: "Type text into a form field matched by a Playwright selector.",
|
|
137
|
+
promptSnippet: "Fill a text input in the browser.",
|
|
138
|
+
parameters: Type.Object({
|
|
139
|
+
selector: Type.String({ description: "Playwright selector for the input (e.g. 'input[name=email]')" }),
|
|
140
|
+
value: Type.String({ description: "Text to type into the field" }),
|
|
141
|
+
}),
|
|
142
|
+
async execute(_toolCallId, params) {
|
|
143
|
+
try {
|
|
144
|
+
const out = await fill(params.selector, params.value);
|
|
145
|
+
return { content: [{ type: "text", text: out || `filled ${params.selector}` }], details: null };
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return { content: [{ type: "text", text: `fill failed: ${err.message}` }], details: null };
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
pi.registerTool({
|
|
153
|
+
name: "playwright_screenshot",
|
|
154
|
+
label: "Browser Screenshot",
|
|
155
|
+
description: "Capture a PNG screenshot of the current page and save to a local file path.",
|
|
156
|
+
promptSnippet: "Take a screenshot of the current browser page.",
|
|
157
|
+
parameters: Type.Object({
|
|
158
|
+
outputPath: Type.String({
|
|
159
|
+
description: "Local file path where the PNG should be written (e.g. '.orient-cli/screenshots/home.png')",
|
|
160
|
+
}),
|
|
161
|
+
}),
|
|
162
|
+
async execute(_toolCallId, params) {
|
|
163
|
+
try {
|
|
164
|
+
const saved = await screenshot(params.outputPath);
|
|
165
|
+
return { content: [{ type: "text", text: `Saved screenshot to ${saved}` }], details: null };
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
return { content: [{ type: "text", text: `screenshot failed: ${err.message}` }], details: null };
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
pi.registerTool({
|
|
173
|
+
name: "playwright_eval",
|
|
174
|
+
label: "Browser Evaluate JS",
|
|
175
|
+
description: "Evaluate a JavaScript expression against the current page. Returns the result as JSON. Use when snapshot text is not enough to extract what you need (e.g. pulling an array of prices from a table).",
|
|
176
|
+
promptSnippet: "Run a JavaScript expression against the current browser page.",
|
|
177
|
+
parameters: Type.Object({
|
|
178
|
+
expression: Type.String({
|
|
179
|
+
description: "JavaScript expression. Example: `Array.from(document.querySelectorAll('.price')).map(el => el.textContent)`",
|
|
180
|
+
}),
|
|
181
|
+
}),
|
|
182
|
+
async execute(_toolCallId, params) {
|
|
183
|
+
try {
|
|
184
|
+
const out = await evaluate(params.expression);
|
|
185
|
+
return { content: [{ type: "text", text: out || "(no result)" }], details: null };
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
return { content: [{ type: "text", text: `eval failed: ${err.message}` }], details: null };
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
pi.registerTool({
|
|
193
|
+
name: "playwright_close",
|
|
194
|
+
label: "Browser Close",
|
|
195
|
+
description: "Close the shared orient browser session cleanly. Call at end-of-task to release the chromium process.",
|
|
196
|
+
promptSnippet: "Close the browser session.",
|
|
197
|
+
parameters: Type.Object({}),
|
|
198
|
+
async execute() {
|
|
199
|
+
try {
|
|
200
|
+
await close();
|
|
201
|
+
return { content: [{ type: "text", text: "Browser session closed." }], details: null };
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return { content: [{ type: "text", text: `close failed: ${err.message}` }], details: null };
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=playwright-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright-extension.js","sourceRoot":"","sources":["../../../src/integrations/playwright/playwright-extension.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web search bridge (MIT, derived from mrkrsl/web-search-mcp)
|
|
3
|
+
* ============================================================
|
|
4
|
+
*
|
|
5
|
+
* ORIENT ships a default web-search layer that uses the same
|
|
6
|
+
* "scrape Bing / Brave / DuckDuckGo via playwright" pattern that
|
|
7
|
+
* https://github.com/mrkrsl/web-search-mcp@MIT implements as a
|
|
8
|
+
* standalone MCP server. We adopt that approach directly in
|
|
9
|
+
* TypeScript here instead of spawning the MCP server as a
|
|
10
|
+
* subprocess — it avoids (a) the MCP protocol overhead, (b) the
|
|
11
|
+
* extra install step, and (c) the dependency on an 8-month-stale
|
|
12
|
+
* upstream build. All three engine scrapers, the priority-order
|
|
13
|
+
* fallback, and the content extraction pattern are reimplemented
|
|
14
|
+
* from the upstream's published README + source layout.
|
|
15
|
+
*
|
|
16
|
+
* Upstream attribution: https://github.com/mrkrsl/web-search-mcp
|
|
17
|
+
* Upstream license: MIT
|
|
18
|
+
*
|
|
19
|
+
* Three operations match the upstream MCP tool surface:
|
|
20
|
+
*
|
|
21
|
+
* - `search(query, { limit, includeContent })` — "full-web-search"
|
|
22
|
+
* equivalent. Returns an array of `SearchResult` with optional
|
|
23
|
+
* full page text content per result.
|
|
24
|
+
*
|
|
25
|
+
* - `searchSummaries(query, { limit })` — "get-web-search-summaries"
|
|
26
|
+
* equivalent. Returns the same shape but with content omitted
|
|
27
|
+
* (faster, no second-pass fetch per URL).
|
|
28
|
+
*
|
|
29
|
+
* - `getPageContent(url)` — "get-single-web-page-content"
|
|
30
|
+
* equivalent. Direct content extraction for one URL the agent
|
|
31
|
+
* already has.
|
|
32
|
+
*
|
|
33
|
+
* Environment variables honored (names match upstream):
|
|
34
|
+
*
|
|
35
|
+
* MAX_CONTENT_LENGTH — max chars returned per page (default 8000)
|
|
36
|
+
* DEFAULT_TIMEOUT — per-navigation timeout in ms (default 20000)
|
|
37
|
+
* BROWSER_HEADLESS — "true" or "false" (default true)
|
|
38
|
+
* FORCE_MULTI_ENGINE_SEARCH — force fallback engines even on Bing hit
|
|
39
|
+
*
|
|
40
|
+
* Playwright is already a dependency of orient-cli (shipped for
|
|
41
|
+
* @playwright/cli and the notebooklm login flow), so importing
|
|
42
|
+
* `playwright` here adds zero additional install weight.
|
|
43
|
+
*/
|
|
44
|
+
export interface SearchResult {
|
|
45
|
+
title: string;
|
|
46
|
+
url: string;
|
|
47
|
+
snippet: string;
|
|
48
|
+
/** Populated only when `includeContent` is true. */
|
|
49
|
+
content?: string;
|
|
50
|
+
/** Which engine produced this result (bing | brave | duckduckgo). */
|
|
51
|
+
engine: "bing" | "brave" | "duckduckgo";
|
|
52
|
+
}
|
|
53
|
+
export interface SearchOptions {
|
|
54
|
+
limit?: number;
|
|
55
|
+
includeContent?: boolean;
|
|
56
|
+
/** Override the default engine priority. */
|
|
57
|
+
engines?: Array<"bing" | "brave" | "duckduckgo">;
|
|
58
|
+
}
|
|
59
|
+
export interface EnvOptions {
|
|
60
|
+
maxContentLength: number;
|
|
61
|
+
defaultTimeout: number;
|
|
62
|
+
headless: boolean;
|
|
63
|
+
forceMulti: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare function closeBrowser(): Promise<void>;
|
|
66
|
+
export declare function getPageContent(url: string): Promise<{
|
|
67
|
+
url: string;
|
|
68
|
+
title: string;
|
|
69
|
+
content: string;
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* Run a web search with the priority-order fallback pattern mrkrsl/
|
|
73
|
+
* web-search-mcp established: try Bing first, fall through to Brave,
|
|
74
|
+
* fall through to DuckDuckGo. If `includeContent` is true, fetch full
|
|
75
|
+
* page text for each result in parallel (bounded to 5 concurrent).
|
|
76
|
+
*/
|
|
77
|
+
export declare function search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
78
|
+
/** Shortcut: search without full content fetch. */
|
|
79
|
+
export declare function searchSummaries(query: string, options?: Omit<SearchOptions, "includeContent">): Promise<SearchResult[]>;
|