@browserbasehq/browse-cli 0.4.1 → 0.4.2-alpha-2df4b01
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/README.md +12 -11
- package/dist/index.js +180 -59
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -173,22 +173,23 @@ browse env
|
|
|
173
173
|
# Switch current session to Browserbase (restarts daemon if needed)
|
|
174
174
|
browse env remote
|
|
175
175
|
|
|
176
|
-
# Switch back to local Chrome (
|
|
176
|
+
# Switch back to local Chrome (clean isolated browser by default)
|
|
177
177
|
browse env local
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
#### Local Browser Strategies
|
|
181
181
|
|
|
182
|
-
By default, `browse env local`
|
|
183
|
-
|
|
184
|
-
If no debuggable Chrome is found, it
|
|
182
|
+
By default, `browse env local` launches a clean isolated local browser.
|
|
183
|
+
Use `browse env local --auto-connect` to opt into reusing an already-running
|
|
184
|
+
Chrome with remote debugging enabled. If no debuggable Chrome is found, it
|
|
185
|
+
falls back to launching an isolated browser.
|
|
185
186
|
|
|
186
187
|
```bash
|
|
187
|
-
#
|
|
188
|
+
# Use a clean isolated browser (default)
|
|
188
189
|
browse env local
|
|
189
190
|
|
|
190
|
-
#
|
|
191
|
-
browse env local --
|
|
191
|
+
# Auto-discover local Chrome, fallback to isolated
|
|
192
|
+
browse env local --auto-connect
|
|
192
193
|
|
|
193
194
|
# Attach to a specific CDP target (port or URL)
|
|
194
195
|
browse env local 9222
|
|
@@ -210,7 +211,7 @@ Use `browse status` to see which strategy was resolved:
|
|
|
210
211
|
|
|
211
212
|
```bash
|
|
212
213
|
browse status
|
|
213
|
-
# {"running":true,"session":"default","mode":"local","localStrategy":"
|
|
214
|
+
# {"running":true,"session":"default","mode":"local","localStrategy":"isolated","localSource":"isolated"}
|
|
214
215
|
```
|
|
215
216
|
|
|
216
217
|
#### General Behavior
|
|
@@ -283,19 +284,19 @@ browse --session personal open https://twitter.com
|
|
|
283
284
|
|
|
284
285
|
## Direct CDP Connection
|
|
285
286
|
|
|
286
|
-
|
|
287
|
+
Opt into using an existing Chrome instance:
|
|
287
288
|
|
|
288
289
|
To make your Chrome discoverable:
|
|
289
290
|
|
|
290
291
|
1. Open `chrome://inspect/#remote-debugging`
|
|
291
292
|
2. Check the box **"Allow remote debugging for this browser instance"**
|
|
292
|
-
3. Re-run the CLI
|
|
293
|
+
3. Re-run the CLI with auto-connect enabled.
|
|
293
294
|
|
|
294
295
|
For more information, see the [Chrome DevTools docs](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session).
|
|
295
296
|
|
|
296
297
|
```bash
|
|
297
298
|
# Auto-discover Chrome with remote debugging enabled
|
|
298
|
-
browse env local
|
|
299
|
+
browse env local --auto-connect
|
|
299
300
|
browse open https://example.com
|
|
300
301
|
|
|
301
302
|
# Or target a specific port / WebSocket URL
|
package/dist/index.js
CHANGED
|
@@ -119791,10 +119791,13 @@ var AISdkClient2 = class extends LLMClient {
|
|
|
119791
119791
|
type = "aisdk";
|
|
119792
119792
|
model;
|
|
119793
119793
|
logger;
|
|
119794
|
-
constructor({ model, logger }) {
|
|
119794
|
+
constructor({ model, logger, clientOptions }) {
|
|
119795
119795
|
super(model.modelId);
|
|
119796
119796
|
this.model = model;
|
|
119797
119797
|
this.logger = logger;
|
|
119798
|
+
if (clientOptions) {
|
|
119799
|
+
this.clientOptions = clientOptions;
|
|
119800
|
+
}
|
|
119798
119801
|
}
|
|
119799
119802
|
getLanguageModel() {
|
|
119800
119803
|
return this.model;
|
|
@@ -119872,9 +119875,11 @@ var AISdkClient2 = class extends LLMClient {
|
|
|
119872
119875
|
let objectResponse;
|
|
119873
119876
|
const isGPT5 = this.model.modelId.includes("gpt-5");
|
|
119874
119877
|
const isCodex = this.model.modelId.includes("codex");
|
|
119875
|
-
const usesLowReasoningEffort = (this.model.modelId.includes("gpt-5.1") || this.model.modelId.includes("gpt-5.2")) && !isCodex;
|
|
119876
119878
|
const isKimi = this.model.modelId.includes("kimi");
|
|
119877
119879
|
const temperature = isKimi ? 1 : options.temperature;
|
|
119880
|
+
const isGPT5SubModel = this.model.modelId.includes("gpt-5.") && !isCodex;
|
|
119881
|
+
const userReasoningEffort = this.clientOptions?.reasoningEffort;
|
|
119882
|
+
const resolvedReasoningEffort = userReasoningEffort ?? (isGPT5SubModel ? "none" : void 0);
|
|
119878
119883
|
const PROMPT_JSON_FALLBACK_PATTERNS = ["deepseek", "kimi", "glm"];
|
|
119879
119884
|
const needsPromptJsonFallback = PROMPT_JSON_FALLBACK_PATTERNS.some((p2) => this.model.modelId.includes(p2));
|
|
119880
119885
|
if (options.response_model) {
|
|
@@ -119903,11 +119908,10 @@ You must respond in JSON format. respond WITH JSON. Do not include any other tex
|
|
|
119903
119908
|
messages: formattedMessages,
|
|
119904
119909
|
schema: options.response_model.schema,
|
|
119905
119910
|
temperature,
|
|
119906
|
-
providerOptions:
|
|
119911
|
+
providerOptions: resolvedReasoningEffort ? {
|
|
119907
119912
|
openai: {
|
|
119908
|
-
textVerbosity: isCodex ? "medium" : "low",
|
|
119909
|
-
|
|
119910
|
-
reasoningEffort: isCodex ? "medium" : usesLowReasoningEffort ? "low" : "minimal"
|
|
119913
|
+
...isGPT5 ? { textVerbosity: isCodex ? "medium" : "low" } : {},
|
|
119914
|
+
reasoningEffort: resolvedReasoningEffort
|
|
119911
119915
|
}
|
|
119912
119916
|
} : void 0
|
|
119913
119917
|
});
|
|
@@ -152796,27 +152800,34 @@ var modelToProviderMap = {
|
|
|
152796
152800
|
"gemini-2.5-flash-preview-04-17": "google",
|
|
152797
152801
|
"gemini-2.5-pro-preview-03-25": "google"
|
|
152798
152802
|
};
|
|
152799
|
-
function getAISDKLanguageModel(subProvider, subModelName, clientOptions) {
|
|
152803
|
+
function getAISDKLanguageModel(subProvider, subModelName, clientOptions, middleware) {
|
|
152800
152804
|
const hasValidOptions = clientOptions && Object.values(clientOptions).some((v2) => v2 !== void 0 && v2 !== null);
|
|
152805
|
+
let model;
|
|
152801
152806
|
if (hasValidOptions) {
|
|
152802
152807
|
const creator = AISDKProvidersWithAPIKey[subProvider];
|
|
152803
152808
|
if (!creator) {
|
|
152804
152809
|
throw new UnsupportedAISDKModelProviderError(subProvider, Object.keys(AISDKProvidersWithAPIKey));
|
|
152805
152810
|
}
|
|
152806
152811
|
const provider = creator(clientOptions);
|
|
152807
|
-
|
|
152812
|
+
model = provider(subModelName);
|
|
152808
152813
|
} else {
|
|
152809
152814
|
const provider = AISDKProviders[subProvider];
|
|
152810
152815
|
if (!provider) {
|
|
152811
152816
|
throw new UnsupportedAISDKModelProviderError(subProvider, Object.keys(AISDKProviders));
|
|
152812
152817
|
}
|
|
152813
|
-
|
|
152818
|
+
model = provider(subModelName);
|
|
152819
|
+
}
|
|
152820
|
+
if (middleware) {
|
|
152821
|
+
return wrapLanguageModel({ model, middleware });
|
|
152814
152822
|
}
|
|
152823
|
+
return model;
|
|
152815
152824
|
}
|
|
152816
152825
|
var LLMProvider = class {
|
|
152817
152826
|
logger;
|
|
152818
|
-
|
|
152827
|
+
middleware;
|
|
152828
|
+
constructor(logger, middleware) {
|
|
152819
152829
|
this.logger = logger;
|
|
152830
|
+
this.middleware = middleware;
|
|
152820
152831
|
}
|
|
152821
152832
|
getClient(modelName, clientOptions, options) {
|
|
152822
152833
|
if (modelName.includes("/")) {
|
|
@@ -152826,10 +152837,12 @@ var LLMProvider = class {
|
|
|
152826
152837
|
if (subProvider === "vertex" && !options?.disableAPI && !options?.experimental) {
|
|
152827
152838
|
throw new ExperimentalNotConfiguredError("Vertex provider");
|
|
152828
152839
|
}
|
|
152829
|
-
const
|
|
152840
|
+
const effectiveMiddleware = options?.middleware ?? this.middleware;
|
|
152841
|
+
const languageModel = getAISDKLanguageModel(subProvider, subModelName, clientOptions, effectiveMiddleware);
|
|
152830
152842
|
return new AISdkClient2({
|
|
152831
152843
|
model: languageModel,
|
|
152832
|
-
logger: this.logger
|
|
152844
|
+
logger: this.logger,
|
|
152845
|
+
clientOptions
|
|
152833
152846
|
});
|
|
152834
152847
|
}
|
|
152835
152848
|
const provider = modelToProviderMap[modelName];
|
|
@@ -162834,13 +162847,14 @@ function resolveModelConfiguration(model) {
|
|
|
162834
162847
|
return { modelName: model };
|
|
162835
162848
|
}
|
|
162836
162849
|
if (model && typeof model === "object") {
|
|
162837
|
-
const { modelName, ...clientOptions } = model;
|
|
162850
|
+
const { modelName, middleware, ...clientOptions } = model;
|
|
162838
162851
|
if (!modelName) {
|
|
162839
162852
|
throw new StagehandInvalidArgumentError("model.modelName is required when providing client options.");
|
|
162840
162853
|
}
|
|
162841
162854
|
return {
|
|
162842
162855
|
modelName,
|
|
162843
|
-
clientOptions
|
|
162856
|
+
clientOptions,
|
|
162857
|
+
middleware
|
|
162844
162858
|
};
|
|
162845
162859
|
}
|
|
162846
162860
|
return { modelName: DEFAULT_MODEL_NAME };
|
|
@@ -163015,11 +163029,11 @@ var V3 = (() => {
|
|
|
163015
163029
|
}
|
|
163016
163030
|
} catch {
|
|
163017
163031
|
}
|
|
163018
|
-
const { modelName, clientOptions } = resolveModelConfiguration(opts.model);
|
|
163032
|
+
const { modelName, clientOptions, middleware } = resolveModelConfiguration(opts.model);
|
|
163019
163033
|
this.modelName = modelName;
|
|
163020
163034
|
this.experimental = opts.experimental ?? false;
|
|
163021
163035
|
this.logInferenceToFile = opts.logInferenceToFile ?? false;
|
|
163022
|
-
this.llmProvider = new LLMProvider(this.logger);
|
|
163036
|
+
this.llmProvider = new LLMProvider(this.logger, middleware);
|
|
163023
163037
|
this.domSettleTimeoutMs = opts.domSettleTimeout;
|
|
163024
163038
|
this.disableAPI = opts.disableAPI ?? false;
|
|
163025
163039
|
const baseClientOptions = clientOptions ? { ...clientOptions } : {};
|
|
@@ -163101,14 +163115,16 @@ var V3 = (() => {
|
|
|
163101
163115
|
}
|
|
163102
163116
|
let modelName;
|
|
163103
163117
|
let clientOptions;
|
|
163118
|
+
let perCallMiddleware;
|
|
163104
163119
|
if (typeof model === "string") {
|
|
163105
163120
|
modelName = model;
|
|
163106
163121
|
} else {
|
|
163107
|
-
const { modelName: overrideModelName, ...rest } = model;
|
|
163122
|
+
const { modelName: overrideModelName, middleware, ...rest } = model;
|
|
163108
163123
|
modelName = overrideModelName;
|
|
163109
163124
|
clientOptions = rest;
|
|
163125
|
+
perCallMiddleware = middleware;
|
|
163110
163126
|
}
|
|
163111
|
-
if (modelName === this.modelName && (!clientOptions || Object.keys(clientOptions).length === 0)) {
|
|
163127
|
+
if (modelName === this.modelName && !perCallMiddleware && (!clientOptions || Object.keys(clientOptions).length === 0)) {
|
|
163112
163128
|
return this.llmClient;
|
|
163113
163129
|
}
|
|
163114
163130
|
const overrideProvider = String(modelName).split("/")[0];
|
|
@@ -163124,6 +163140,13 @@ var V3 = (() => {
|
|
|
163124
163140
|
mergedOptions.apiKey = apiKey;
|
|
163125
163141
|
}
|
|
163126
163142
|
}
|
|
163143
|
+
if (perCallMiddleware) {
|
|
163144
|
+
return this.llmProvider.getClient(modelName, mergedOptions, {
|
|
163145
|
+
experimental: this.experimental,
|
|
163146
|
+
disableAPI: this.disableAPI,
|
|
163147
|
+
middleware: perCallMiddleware
|
|
163148
|
+
});
|
|
163149
|
+
}
|
|
163127
163150
|
const cacheKey = JSON.stringify({
|
|
163128
163151
|
modelName,
|
|
163129
163152
|
clientOptions: mergedOptions
|
|
@@ -163132,7 +163155,10 @@ var V3 = (() => {
|
|
|
163132
163155
|
if (cached2) {
|
|
163133
163156
|
return cached2;
|
|
163134
163157
|
}
|
|
163135
|
-
const client = this.llmProvider.getClient(modelName, mergedOptions, {
|
|
163158
|
+
const client = this.llmProvider.getClient(modelName, mergedOptions, {
|
|
163159
|
+
experimental: this.experimental,
|
|
163160
|
+
disableAPI: this.disableAPI
|
|
163161
|
+
});
|
|
163136
163162
|
this.overrideLlmClients.set(cacheKey, client);
|
|
163137
163163
|
return client;
|
|
163138
163164
|
}
|
|
@@ -164626,7 +164652,72 @@ var import_child_process4 = require("child_process");
|
|
|
164626
164652
|
var readline = __toESM(require("readline"));
|
|
164627
164653
|
|
|
164628
164654
|
// package.json
|
|
164629
|
-
var version3 = "0.4.
|
|
164655
|
+
var version3 = "0.4.2";
|
|
164656
|
+
|
|
164657
|
+
// src/local-strategy.ts
|
|
164658
|
+
init_cjs_shims();
|
|
164659
|
+
var DEFAULT_LOCAL_CONFIG = { strategy: "isolated" };
|
|
164660
|
+
var ISOLATED_MODE_HINT = "Hint: Run `browse env local --auto-connect` to reuse your local browsing credentials and cookies.";
|
|
164661
|
+
var ATTACHED_EXISTING_HINT = "Hint: Run `browse env local` without `--auto-connect` to switch back to an isolated Chromium browser.";
|
|
164662
|
+
function getLocalModeHint(localConfig, localInfo) {
|
|
164663
|
+
if (localInfo?.localSource === "attached-existing") {
|
|
164664
|
+
return ATTACHED_EXISTING_HINT;
|
|
164665
|
+
}
|
|
164666
|
+
if (localInfo?.localSource === "isolated-fallback") {
|
|
164667
|
+
return null;
|
|
164668
|
+
}
|
|
164669
|
+
if (localConfig.strategy === "auto" && !localInfo) {
|
|
164670
|
+
return ATTACHED_EXISTING_HINT;
|
|
164671
|
+
}
|
|
164672
|
+
if (localInfo?.localSource === "isolated" || localConfig.strategy === "isolated" && !localInfo) {
|
|
164673
|
+
return ISOLATED_MODE_HINT;
|
|
164674
|
+
}
|
|
164675
|
+
return null;
|
|
164676
|
+
}
|
|
164677
|
+
async function resolveLocalStrategy({
|
|
164678
|
+
localConfig,
|
|
164679
|
+
headless,
|
|
164680
|
+
defaultViewport,
|
|
164681
|
+
discoverLocalCdp: discoverLocalCdp2,
|
|
164682
|
+
resolveWsTarget: resolveWsTarget2
|
|
164683
|
+
}) {
|
|
164684
|
+
if (localConfig.strategy === "isolated") {
|
|
164685
|
+
return {
|
|
164686
|
+
localLaunchOptions: { headless, viewport: defaultViewport },
|
|
164687
|
+
localInfo: { localSource: "isolated" }
|
|
164688
|
+
};
|
|
164689
|
+
}
|
|
164690
|
+
if (localConfig.strategy === "cdp") {
|
|
164691
|
+
if (!localConfig.cdpTarget) {
|
|
164692
|
+
throw new Error("Local CDP strategy requires a cdpTarget");
|
|
164693
|
+
}
|
|
164694
|
+
const cdpUrl = await resolveWsTarget2(localConfig.cdpTarget);
|
|
164695
|
+
return {
|
|
164696
|
+
localLaunchOptions: { cdpUrl },
|
|
164697
|
+
localInfo: {
|
|
164698
|
+
localSource: "attached-explicit",
|
|
164699
|
+
resolvedCdpUrl: cdpUrl
|
|
164700
|
+
}
|
|
164701
|
+
};
|
|
164702
|
+
}
|
|
164703
|
+
const discovered = await discoverLocalCdp2();
|
|
164704
|
+
if (discovered) {
|
|
164705
|
+
return {
|
|
164706
|
+
localLaunchOptions: { cdpUrl: discovered.wsUrl },
|
|
164707
|
+
localInfo: {
|
|
164708
|
+
localSource: "attached-existing",
|
|
164709
|
+
resolvedCdpUrl: discovered.wsUrl
|
|
164710
|
+
}
|
|
164711
|
+
};
|
|
164712
|
+
}
|
|
164713
|
+
return {
|
|
164714
|
+
localLaunchOptions: { headless, viewport: defaultViewport },
|
|
164715
|
+
localInfo: {
|
|
164716
|
+
localSource: "isolated-fallback",
|
|
164717
|
+
fallbackReason: "no debuggable local browser found"
|
|
164718
|
+
}
|
|
164719
|
+
};
|
|
164720
|
+
}
|
|
164630
164721
|
|
|
164631
164722
|
// src/resolve-ws.ts
|
|
164632
164723
|
init_cjs_shims();
|
|
@@ -164651,6 +164742,7 @@ async function resolveWsTarget(input) {
|
|
|
164651
164742
|
}
|
|
164652
164743
|
|
|
164653
164744
|
// src/index.ts
|
|
164745
|
+
var import_node_html_markdown = require("node-html-markdown");
|
|
164654
164746
|
var program = new import_commander.Command();
|
|
164655
164747
|
var SOCKET_DIR = os3.tmpdir();
|
|
164656
164748
|
function getSocketPath(session) {
|
|
@@ -164756,7 +164848,7 @@ async function readLocalConfig(session) {
|
|
|
164756
164848
|
const raw = await import_fs11.promises.readFile(getLocalConfigPath(session), "utf-8");
|
|
164757
164849
|
return JSON.parse(raw);
|
|
164758
164850
|
} catch {
|
|
164759
|
-
return {
|
|
164851
|
+
return { ...DEFAULT_LOCAL_CONFIG };
|
|
164760
164852
|
}
|
|
164761
164853
|
}
|
|
164762
164854
|
async function writeLocalConfig(session, config3) {
|
|
@@ -164773,6 +164865,23 @@ async function readLocalInfo(session) {
|
|
|
164773
164865
|
return null;
|
|
164774
164866
|
}
|
|
164775
164867
|
}
|
|
164868
|
+
async function waitForLocalInfo(session, timeoutMs = 1500) {
|
|
164869
|
+
const startTime = Date.now();
|
|
164870
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
164871
|
+
const localInfo = await readLocalInfo(session);
|
|
164872
|
+
if (localInfo) {
|
|
164873
|
+
return localInfo;
|
|
164874
|
+
}
|
|
164875
|
+
await new Promise((resolve4) => setTimeout(resolve4, 50));
|
|
164876
|
+
}
|
|
164877
|
+
return readLocalInfo(session);
|
|
164878
|
+
}
|
|
164879
|
+
function logLocalModeHint(localConfig, localInfo) {
|
|
164880
|
+
const hint = getLocalModeHint(localConfig, localInfo);
|
|
164881
|
+
if (hint) {
|
|
164882
|
+
console.error(hint);
|
|
164883
|
+
}
|
|
164884
|
+
}
|
|
164776
164885
|
function hasBrowserbaseCredentials() {
|
|
164777
164886
|
return Boolean(process.env.BROWSERBASE_API_KEY);
|
|
164778
164887
|
}
|
|
@@ -165070,33 +165179,15 @@ async function runDaemon(session, headless) {
|
|
|
165070
165179
|
let localLaunchOptions;
|
|
165071
165180
|
let localInfo;
|
|
165072
165181
|
if (!useBrowserbase) {
|
|
165073
|
-
const
|
|
165074
|
-
|
|
165075
|
-
|
|
165076
|
-
|
|
165077
|
-
|
|
165078
|
-
|
|
165079
|
-
|
|
165080
|
-
|
|
165081
|
-
|
|
165082
|
-
resolvedCdpUrl: cdpUrl
|
|
165083
|
-
};
|
|
165084
|
-
} else {
|
|
165085
|
-
const discovered = await discoverLocalCdp();
|
|
165086
|
-
if (discovered) {
|
|
165087
|
-
localLaunchOptions = { cdpUrl: discovered.wsUrl };
|
|
165088
|
-
localInfo = {
|
|
165089
|
-
localSource: "attached-existing",
|
|
165090
|
-
resolvedCdpUrl: discovered.wsUrl
|
|
165091
|
-
};
|
|
165092
|
-
} else {
|
|
165093
|
-
localLaunchOptions = { headless, viewport: DEFAULT_VIEWPORT2 };
|
|
165094
|
-
localInfo = {
|
|
165095
|
-
localSource: "isolated-fallback",
|
|
165096
|
-
fallbackReason: "no debuggable local browser found"
|
|
165097
|
-
};
|
|
165098
|
-
}
|
|
165099
|
-
}
|
|
165182
|
+
const resolvedLocalStrategy = await resolveLocalStrategy({
|
|
165183
|
+
localConfig: await readLocalConfig(session),
|
|
165184
|
+
headless,
|
|
165185
|
+
defaultViewport: DEFAULT_VIEWPORT2,
|
|
165186
|
+
discoverLocalCdp,
|
|
165187
|
+
resolveWsTarget
|
|
165188
|
+
});
|
|
165189
|
+
localLaunchOptions = resolvedLocalStrategy.localLaunchOptions;
|
|
165190
|
+
localInfo = resolvedLocalStrategy.localInfo;
|
|
165100
165191
|
}
|
|
165101
165192
|
stagehand = new V3({
|
|
165102
165193
|
env: useBrowserbase ? "BROWSERBASE" : "LOCAL",
|
|
@@ -165472,6 +165563,11 @@ async function executeCommand(context, command, args, stagehand) {
|
|
|
165472
165563
|
return {
|
|
165473
165564
|
checked: await page.deepLocator(resolveSelector(selector)).isChecked()
|
|
165474
165565
|
};
|
|
165566
|
+
case "markdown": {
|
|
165567
|
+
const target = selector ? resolveSelector(selector) : "body";
|
|
165568
|
+
const html = await page.deepLocator(target).innerHtml();
|
|
165569
|
+
return { markdown: import_node_html_markdown.NodeHtmlMarkdown.translate(html) };
|
|
165570
|
+
}
|
|
165475
165571
|
default:
|
|
165476
165572
|
throw new Error(`Unknown get type: ${what}`);
|
|
165477
165573
|
}
|
|
@@ -166040,7 +166136,8 @@ program.command("status").description("Check daemon status").action(async () =>
|
|
|
166040
166136
|
}
|
|
166041
166137
|
if (mode === "local") {
|
|
166042
166138
|
const localConfig = await readLocalConfig(session);
|
|
166043
|
-
const localInfo = await readLocalInfo(session);
|
|
166139
|
+
const localInfo = await readLocalInfo(session) ?? await waitForLocalInfo(session);
|
|
166140
|
+
logLocalModeHint(localConfig, localInfo);
|
|
166044
166141
|
localDetails = {
|
|
166045
166142
|
localStrategy: localConfig.strategy,
|
|
166046
166143
|
...localInfo ?? {}
|
|
@@ -166058,9 +166155,20 @@ program.command("status").description("Check daemon status").action(async () =>
|
|
|
166058
166155
|
})
|
|
166059
166156
|
);
|
|
166060
166157
|
});
|
|
166061
|
-
|
|
166062
|
-
|
|
166063
|
-
)
|
|
166158
|
+
var envUsage = "Usage: browse env [local|remote]\n browse env local [--auto-connect|<port|url>]";
|
|
166159
|
+
var envCommand = program.command("env [target] [cdpTarget]").description(
|
|
166160
|
+
"Show or switch browser environment (local | remote)\n\n browse env Show current environment\n browse env local Use clean isolated local browser (default)\n browse env local --auto-connect Auto-discover local Chrome, fallback to isolated\n browse env local <port|url> Attach to specific CDP target\n browse env remote Use Browserbase (requires API key)"
|
|
166161
|
+
).option(
|
|
166162
|
+
"--auto-connect",
|
|
166163
|
+
"Auto-discover an existing local Chrome instance via CDP"
|
|
166164
|
+
);
|
|
166165
|
+
envCommand.addOption(
|
|
166166
|
+
new import_commander.Option(
|
|
166167
|
+
"--isolated",
|
|
166168
|
+
"Deprecated alias for the default isolated local browser"
|
|
166169
|
+
).hideHelp()
|
|
166170
|
+
);
|
|
166171
|
+
envCommand.action(
|
|
166064
166172
|
async (target, cdpTarget, cmdOpts) => {
|
|
166065
166173
|
const opts = program.opts();
|
|
166066
166174
|
const session = getSession(opts);
|
|
@@ -166091,9 +166199,7 @@ program.command("env [target] [cdpTarget]").description(
|
|
|
166091
166199
|
};
|
|
166092
166200
|
const mapped = modeMap[target];
|
|
166093
166201
|
if (!mapped) {
|
|
166094
|
-
console.error(
|
|
166095
|
-
"Usage: browse env [local|remote]\n browse env local [--isolated] [<port|url>]"
|
|
166096
|
-
);
|
|
166202
|
+
console.error(envUsage);
|
|
166097
166203
|
process.exit(1);
|
|
166098
166204
|
}
|
|
166099
166205
|
try {
|
|
@@ -166102,10 +166208,22 @@ program.command("env [target] [cdpTarget]").description(
|
|
|
166102
166208
|
console.error(err instanceof Error ? err.message : String(err));
|
|
166103
166209
|
process.exit(1);
|
|
166104
166210
|
}
|
|
166105
|
-
let localConfig = {
|
|
166211
|
+
let localConfig = { ...DEFAULT_LOCAL_CONFIG };
|
|
166106
166212
|
if (mapped === "local") {
|
|
166107
|
-
|
|
166108
|
-
|
|
166213
|
+
const selectedLocalStrategies = [
|
|
166214
|
+
Boolean(cmdOpts.autoConnect),
|
|
166215
|
+
Boolean(cmdOpts.isolated),
|
|
166216
|
+
Boolean(cdpTarget)
|
|
166217
|
+
].filter(Boolean);
|
|
166218
|
+
if (selectedLocalStrategies.length > 1) {
|
|
166219
|
+
console.error(envUsage);
|
|
166220
|
+
console.error(
|
|
166221
|
+
"Use only one of --auto-connect, --isolated, or <port|url>."
|
|
166222
|
+
);
|
|
166223
|
+
process.exit(1);
|
|
166224
|
+
}
|
|
166225
|
+
if (cmdOpts.autoConnect) {
|
|
166226
|
+
localConfig = { strategy: "auto" };
|
|
166109
166227
|
} else if (cdpTarget) {
|
|
166110
166228
|
localConfig = { strategy: "cdp", cdpTarget };
|
|
166111
166229
|
}
|
|
@@ -166128,6 +166246,9 @@ program.command("env [target] [cdpTarget]").description(
|
|
|
166128
166246
|
await stopDaemonAndCleanup(session);
|
|
166129
166247
|
}
|
|
166130
166248
|
await ensureDaemon(session, isHeadless(opts));
|
|
166249
|
+
if (mapped === "local") {
|
|
166250
|
+
logLocalModeHint(localConfig, await waitForLocalInfo(session));
|
|
166251
|
+
}
|
|
166131
166252
|
console.log(
|
|
166132
166253
|
JSON.stringify({
|
|
166133
166254
|
mode: toModeTarget(mapped),
|
|
@@ -166401,7 +166522,7 @@ program.command("highlight <selector>").description("Highlight element").option(
|
|
|
166401
166522
|
}
|
|
166402
166523
|
});
|
|
166403
166524
|
program.command("get <what> [selector]").description(
|
|
166404
|
-
"Get page info: url, title, text, html, value, box, visible, checked"
|
|
166525
|
+
"Get page info: url, title, text, html, markdown, value, box, visible, checked"
|
|
166405
166526
|
).action(async (what, selector) => {
|
|
166406
166527
|
const opts = program.opts();
|
|
166407
166528
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserbasehq/browse-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2-alpha-2df4b01",
|
|
4
4
|
"description": "Browser automation CLI for AI agents, built on Stagehand",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,10 +44,11 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"commander": "^12.0.0",
|
|
46
46
|
"dotenv": "^16.4.5",
|
|
47
|
+
"node-html-markdown": "^1.3.0",
|
|
47
48
|
"pino": "^9.6.0",
|
|
48
49
|
"pino-pretty": "^13.0.0",
|
|
49
50
|
"ws": "^8.18.0",
|
|
50
|
-
"@browserbasehq/stagehand": "3.2.
|
|
51
|
+
"@browserbasehq/stagehand": "3.2.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@types/node": "^20.11.30",
|