@opencode/browse 0.0.6-dev.20 → 0.0.6-dev.21

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.
@@ -1,14 +1,22 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ opencodeBrowserVersion2,
4
+ opencodeBrowserBuildId2
5
+ } from "./main-ek76h9k1.mjs";
2
6
  import {
3
7
  dataRoot,
4
8
  fromCheckout,
9
+ compiledBinary,
10
+ binaryPackage,
5
11
  cliCommand,
6
12
  devExtension,
7
13
  installCommand,
8
- autoUpdateStatus,
14
+ autoUpdateStatus
15
+ } from "./main-0m569gdn.mjs";
16
+ import {
9
17
  extensionProtocolVersion,
10
18
  extensionProtocolAdvice
11
- } from "./main-ma25hhqh.mjs";
19
+ } from "./main-3gthmkzw.mjs";
12
20
  import {
13
21
  defaultPort2,
14
22
  isValidSessionId2,
@@ -27,17 +35,13 @@ import {
27
35
  ensureExtensionConnected,
28
36
  stoppedRelayStatus,
29
37
  statusCollections
30
- } from "./main-0nta0a2z.mjs";
31
- import"./main-20ahaz2q.mjs";
32
- import {
33
- opencodeBrowserVersion2,
34
- opencodeBrowserBuildId2
35
- } from "./main-arx3pfyn.mjs";
38
+ } from "./main-qm2keaeb.mjs";
39
+ import"./main-7qs0mwvc.mjs";
36
40
  import {
37
41
  updateJson2,
38
42
  formatUpdateNotice2,
39
43
  updateNotice2
40
- } from "./main-3rsfghef.mjs";
44
+ } from "./main-33kf3cfr.mjs";
41
45
  import {
42
46
  settingKeys,
43
47
  formatSettings,
@@ -50,19 +54,19 @@ import {
50
54
  addSecret,
51
55
  listSecrets,
52
56
  removeSecret
53
- } from "./main-yd1d7qr1.mjs";
57
+ } from "./main-yq58hnwq.mjs";
54
58
  import {
55
59
  defaultJournalBaseDir,
56
60
  readJournalEntries,
57
61
  formatJournalEntry
58
- } from "./main-42qfr69q.mjs";
62
+ } from "./main-ybvatjk0.mjs";
59
63
 
60
64
  // src/cli.ts
61
65
  import { NodeRuntime, NodeServices } from "@effect/platform-node";
62
66
  import { Console as Console9, Effect as Effect11, Layer as Layer2 } from "effect";
63
67
  import { CliError, Command as Command8 } from "effect/cli";
64
- import path6 from "node:path";
65
- import process3 from "node:process";
68
+ import path5 from "node:path";
69
+ import process4 from "node:process";
66
70
  import { fileURLToPath, pathToFileURL } from "node:url";
67
71
 
68
72
  // src/cli/output.ts
@@ -104,9 +108,8 @@ var printJson = (value) => writeStdout(`${JSON.stringify(value, null, 2)}
104
108
  `);
105
109
 
106
110
  // src/cli/browser.ts
107
- import { Console as Console2, Effect as Effect4, FileSystem as FileSystem3, Option as Option3, Result } from "effect";
111
+ import { Console as Console2, Effect as Effect4, Option as Option3, Result } from "effect";
108
112
  import { Argument, Command, Flag as Flag2 } from "effect/cli";
109
- import path from "node:path";
110
113
 
111
114
  // src/doctor.ts
112
115
  import { Effect as Effect2, FileSystem as FileSystem2, Path as Path2, Schema as Schema2 } from "effect";
@@ -209,7 +212,8 @@ var createDoctorReport = Effect2.fn("Doctor.createReport")(function* (options) {
209
212
  try: () => JSON.parse(text),
210
213
  catch: () => new Error(`parse ${relativePath}: invalid JSON`)
211
214
  })), Effect2.flatMap((value) => Schema2.decodeUnknownEffect(schema)(value).pipe(Effect2.mapError((cause) => new Error(`decode ${relativePath}: ${cause.message}`)))));
212
- const readPackageInfo = readJsonFile("package.json", PackageMetadata).pipe(Effect2.map((metadata) => ({
215
+ const compiled = compiledBinary();
216
+ const readPackageInfo = compiled ? Effect2.succeed({ name: binaryPackage() ?? "@opencode/browse", version: opencodeBrowserVersion2, bin: { opencodeBrowser: process.execPath } }) : readJsonFile("package.json", PackageMetadata).pipe(Effect2.map((metadata) => ({
213
217
  name: metadata.name,
214
218
  version: metadata.version,
215
219
  bin: {
@@ -252,9 +256,7 @@ var createDoctorReport = Effect2.fn("Doctor.createReport")(function* (options) {
252
256
  const possibleLeakedSessions = sessions.filter((session) => {
253
257
  return session.connected && session.id !== current;
254
258
  });
255
- const artifacts = [
256
- { path: "dist/cli.mjs", exists: distCliExists }
257
- ];
259
+ const artifacts = compiled ? [{ path: process.execPath, exists: true, version: opencodeBrowserVersion2 }] : [{ path: "dist/cli.mjs", exists: distCliExists }];
258
260
  const checks = buildDoctorChecks({
259
261
  packageResult,
260
262
  relayResult,
@@ -512,11 +514,11 @@ function buildDoctorRecommendations(options) {
512
514
  `Run a relay-backed command to start the detached relay automatically; use \`${cliCommand("serve")}\` only for foreground debugging.`
513
515
  ];
514
516
  const relayBuildRecommendations = options.relayResult.ok ? [relayBuildProblem(options.relayResult.value)].filter((message) => message !== undefined) : [];
515
- const extensionRecommendations = options.relayResult.ok && options.extensionResult.ok && !options.extensionResult.value.connected ? options.extensionResult.value.nextStep ? [options.extensionResult.value.nextStep] : options.extensionResult.value.protocolCompatible === false ? [extensionProtocolAdvice(options.extensionResult.value.protocolVersion, { install: installCommand() })] : [fromCheckout() || devExtension() ? `Run \`${installCommand()}\` and load the extension it points to (Load unpacked on your browser's extensions page).` : `Run \`${installCommand()}\`, and install Browse from the Chrome Web Store page it opens.`] : [];
517
+ const extensionRecommendations = options.relayResult.ok && options.extensionResult.ok && !options.extensionResult.value.connected ? options.extensionResult.value.nextStep ? [options.extensionResult.value.nextStep] : options.extensionResult.value.protocolCompatible === false ? [extensionProtocolAdvice(options.extensionResult.value.protocolVersion, { install: installCommand() })] : [fromCheckout() || devExtension() ? `Run \`${installCommand()}\` and load the extension it points to (Load unpacked on your browser's extensions page).` : `Run \`${installCommand()}\`, and install browse from the Chrome Web Store page it opens.`] : [];
516
518
  const artifactRecommendations = options.artifacts.some((artifact) => {
517
519
  return !artifact.exists;
518
520
  }) ? [`Rebuild or reinstall the missing files with \`${installCommand()}\`.`] : [];
519
- const connectionConflictRecommendations = options.extensionResult.ok && (options.extensionResult.value.rejectedConnections ?? 0) > 0 ? ["Keep Browse enabled in one browser/profile. To switch, disable it in the current browser before connecting the other; new sessions do not change the active browser."] : [];
521
+ const connectionConflictRecommendations = options.extensionResult.ok && (options.extensionResult.value.rejectedConnections ?? 0) > 0 ? ["Keep browse enabled in one browser/profile. To switch, disable it in the current browser before connecting the other; new sessions do not change the active browser."] : [];
520
522
  const staleSessionRecommendations = options.staleCurrent && options.current ? [
521
523
  `Current session ${options.current} is stale; run \`${cliCommand("session new")}\` or \`${cliCommand("session use <id>")}\` after the relay is running.`
522
524
  ] : [];
@@ -549,7 +551,7 @@ function summarizeCheckStatus(checks) {
549
551
  }
550
552
  function formatDoctorReport(report) {
551
553
  const lines = [
552
- "Browse doctor",
554
+ "browse doctor",
553
555
  `Status: ${report.status}`,
554
556
  `Endpoint: ${report.endpoint}`,
555
557
  `CLI: ${report.cli.version} (${report.cli.buildId})`,
@@ -609,7 +611,7 @@ function formatTargetSummary(target, options = {}) {
609
611
  // src/cli/context.ts
610
612
  import { Config, Console, Effect as Effect3, Option as Option2, Predicate as Predicate2 } from "effect";
611
613
  import { Flag } from "effect/cli";
612
- import process from "node:process";
614
+ import process2 from "node:process";
613
615
  var sessionIdConfig = Config.option(Config.String("OPENCODE_BROWSER_SESSION"));
614
616
  var agentSessionIdConfig = Config.option(Config.String("OPENCODE_SESSION_ID"));
615
617
  var targetUrlConfig = Config.option(Config.String("OPENCODE_BROWSER_TARGET_URL"));
@@ -626,10 +628,10 @@ var tabIdFlag = (description) => {
626
628
  return description ? flag.pipe(Flag.withDescription(description)) : flag;
627
629
  };
628
630
  var failExit = Effect3.sync(() => {
629
- process.exitCode = ExitCode.failure;
631
+ process2.exitCode = ExitCode.failure;
630
632
  });
631
633
  var exitWith = (code) => Effect3.sync(() => {
632
- process.exitCode = code;
634
+ process2.exitCode = code;
633
635
  });
634
636
  var hostErrorTags = new Set([
635
637
  "RelayClient.RelayUnreachable",
@@ -650,7 +652,7 @@ function hoistJsonFlag(args) {
650
652
  return { json, argv: [...argv, "--json", ...delimiter === -1 ? [] : args.slice(delimiter)] };
651
653
  }
652
654
  var stderrLine = (message) => Effect3.sync(() => {
653
- process.stderr.write(`opencode-browser: ${message.split(`
655
+ process2.stderr.write(`opencode-browser: ${message.split(`
654
656
  `)[0].slice(0, 300)}
655
657
  `);
656
658
  });
@@ -703,7 +705,7 @@ var ensureCliRelay = Effect3.fnUntraced(function* () {
703
705
  const relay = yield* Service;
704
706
  const readiness = yield* ensureRelay({ relay });
705
707
  if (readiness.started) {
706
- yield* Console.error(`Started Browse relay at ${relay.endpoint}`);
708
+ yield* Console.error(`Started browse relay at ${relay.endpoint}`);
707
709
  }
708
710
  if (readiness.buildProblem) {
709
711
  return yield* Effect3.fail(new Error(readiness.buildProblem));
@@ -717,14 +719,14 @@ var ensureCliRelayAndExtension = Effect3.fnUntraced(function* (sessionId) {
717
719
  relay,
718
720
  sessionId,
719
721
  waitForReconnect: shouldWaitForExtensionReconnect(readiness),
720
- onWait: Console.error(`Waiting up to ${extensionReconnectWaitMs / 1000}s for the Browse extension to reconnect`)
722
+ onWait: Console.error(`Waiting up to ${extensionReconnectWaitMs / 1000}s for the browse extension to reconnect`)
721
723
  });
722
724
  });
723
725
  var resolveSelectedSessionId = Effect3.fnUntraced(function* (explicitSessionId) {
724
726
  const store = yield* Service2;
725
727
  const sessionId = explicitSessionId ?? (yield* store.read);
726
728
  if (!sessionId) {
727
- return yield* Effect3.fail(new Error("No session provided and no current Browse session exists"));
729
+ return yield* Effect3.fail(new Error("No session provided and no current browse session exists"));
728
730
  }
729
731
  return sessionId;
730
732
  });
@@ -893,7 +895,7 @@ var status = Command.make("status", {
893
895
  }
894
896
  yield* Console2.log(`Extension: ${extensionStatus.connected ? "connected" : "disconnected"}${extensionStatus.version ? ` (${extensionStatus.version})` : ""}`);
895
897
  if ((extensionStatus.rejectedConnections ?? 0) > 0) {
896
- yield* Console2.log(`Warning: ${extensionStatus.rejectedConnections} competing browser/profile connection attempt(s) rejected; the active connection was preserved. Use Browse in one browser/profile at a time.`);
898
+ yield* Console2.log(`Warning: ${extensionStatus.rejectedConnections} competing browser/profile connection attempt(s) rejected; the active connection was preserved. Use browse in one browser/profile at a time.`);
897
899
  }
898
900
  if (extensionStatus.nextStep)
899
901
  yield* Console2.log(extensionStatus.nextStep);
@@ -948,9 +950,9 @@ var status = Command.make("status", {
948
950
  }
949
951
  })).pipe(Command.withDescription("Show relay, extension, and target status"));
950
952
  var mcp = Command.make("mcp", {}, Effect4.fn("Cli.mcp")(function* () {
951
- const { runMcpServer } = yield* Effect4.promise(() => import("./mcp-j9e2da4y.mjs"));
953
+ const { runMcpServer } = yield* Effect4.promise(() => import("./mcp-qmq1yerr.mjs"));
952
954
  yield* runMcpServer;
953
- })).pipe(Command.withDescription("Run the Browse MCP server over stdio"));
955
+ })).pipe(Command.withDescription("Run the browse MCP server over stdio"));
954
956
  registerCliCommand(400, () => tabs);
955
957
  registerCliCommand(410, () => settings);
956
958
  registerCliCommand(500, () => status);
@@ -967,21 +969,20 @@ registerCliCommand(810, ({ packageRoot }) => Command.make("doctor", {
967
969
  if (report.status === "fail") {
968
970
  yield* failExit;
969
971
  }
970
- })).pipe(Command.withDescription("Diagnose the local Browse install and runtime")));
971
- registerCliCommand(820, ({ packageRoot }) => Command.make("skill", {}, Effect4.fn("Cli.skill")(function* () {
972
- const fs = yield* FileSystem3.FileSystem;
973
- const text = yield* fs.readFileString(path.join(packageRoot, "skills", "browse", "SKILL.md")).pipe(Effect4.mapError((cause) => new Error("read opencode-browser skill", { cause })));
974
- yield* Console2.log(text.trimEnd());
975
- })).pipe(Command.withDescription("Print the Browse agent skill text")));
972
+ })).pipe(Command.withDescription("Diagnose the local browse install and runtime")));
973
+ registerCliCommand(820, () => Command.make("skill", {}, Effect4.fn("Cli.skill")(function* () {
974
+ const { skillText } = yield* Effect4.promise(() => import("./skill-text-v35020jn.mjs"));
975
+ yield* Console2.log(skillText.trimEnd());
976
+ })).pipe(Command.withDescription("Print the browse agent skill text")));
976
977
  registerCliCommand(900, () => mcp);
977
978
 
978
979
  // src/cli/execute.ts
979
- import { Console as Console3, Effect as Effect5, FileSystem as FileSystem4, Option as Option4, Predicate as Predicate3, Result as Result2, Schema as Schema3 } from "effect";
980
+ import { Console as Console3, Effect as Effect5, FileSystem as FileSystem3, Option as Option4, Predicate as Predicate3, Result as Result2, Schema as Schema3 } from "effect";
980
981
  import { Argument as Argument2, Command as Command2, Flag as Flag3 } from "effect/cli";
981
- import path2 from "node:path";
982
+ import path from "node:path";
982
983
  var readExecuteFile = Effect5.fnUntraced(function* (filePath) {
983
- const fs = yield* FileSystem4.FileSystem;
984
- return yield* fs.readFileString(path2.resolve(filePath)).pipe(Effect5.mapError((cause) => new Error(`read execute file ${filePath}: ${cause.reason.message}`, { cause })));
984
+ const fs = yield* FileSystem3.FileSystem;
985
+ return yield* fs.readFileString(path.resolve(filePath)).pipe(Effect5.mapError((cause) => new Error(`read execute file ${filePath}: ${cause.reason.message}`, { cause })));
985
986
  });
986
987
  function formatExecuteLogs(logs) {
987
988
  return [
@@ -1046,7 +1047,7 @@ function errorJsonEnvelope(error) {
1046
1047
  var execute = Command2.make("execute", {
1047
1048
  code: Argument2.String("code").pipe(Argument2.variadic({ min: 0 })),
1048
1049
  file: Flag3.String("file").pipe(Flag3.optional, Flag3.withDescription("Read execute code from a file")),
1049
- session: sessionFlag("Continue an existing Browse session; defaults to the OpenCode agent's session"),
1050
+ session: sessionFlag("Continue an existing browse session; defaults to the OpenCode agent's session"),
1050
1051
  rm: Flag3.Boolean("rm").pipe(Flag3.withDefault(false), Flag3.withDescription("Use a fresh one-shot session and close its tabs afterward")),
1051
1052
  timeoutMs: Flag3.Int("timeout-ms").pipe(Flag3.optional, Flag3.withDescription("Overall script timeout in milliseconds (paused during handoff); defaults to 60000, 0 disables")),
1052
1053
  targetUrl: Flag3.String("target-url").pipe(Flag3.optional, Flag3.withDescription("Use the attached page whose URL contains this text")),
@@ -1139,7 +1140,7 @@ registerCliCommand(200, () => execute);
1139
1140
  // src/cli/network.ts
1140
1141
  import { Console as Console4, Effect as Effect6, Option as Option5 } from "effect";
1141
1142
  import { Command as Command3, Flag as Flag4 } from "effect/cli";
1142
- import path3 from "node:path";
1143
+ import path2 from "node:path";
1143
1144
  var parseNetworkContent = Effect6.fnUntraced(function* (content) {
1144
1145
  const value = Option5.getOrUndefined(content);
1145
1146
  if (value === undefined || value === "embed" || value === "omit")
@@ -1157,7 +1158,7 @@ function formatNetworkResult(result) {
1157
1158
  return `Network capture stopped: entries=${result.entryCount} responses=${result.responseCount} failures=${result.failureCount} bodyBytes=${result.capturedBodyBytes} truncated=${result.truncatedBodyCount} dropped=${result.droppedEntryCount}${output}${profile}`;
1158
1159
  }
1159
1160
  var networkStart = Command3.make("start", {
1160
- session: sessionFlag("Capture the default page for this Browse session"),
1161
+ session: sessionFlag("Capture the default page for this browse session"),
1161
1162
  urlFilter: Flag4.String("url").pipe(Flag4.optional, Flag4.withDescription("Capture only requests whose URL contains this text")),
1162
1163
  resourceTypes: Flag4.String("resource-type").pipe(Flag4.atMost(50), Flag4.withDescription("Capture this Playwright resource type; repeat for multiple types")),
1163
1164
  content: Flag4.String("content").pipe(Flag4.optional, Flag4.withDescription("Response and request body mode: embed (default) or omit")),
@@ -1219,7 +1220,7 @@ var networkStop = Command3.make("stop", {
1219
1220
  yield* ensureCliRelay();
1220
1221
  const result = yield* relay.networkStop({
1221
1222
  sessionId,
1222
- ...outputValue ? { outputPath: path3.resolve(outputValue) } : {},
1223
+ ...outputValue ? { outputPath: path2.resolve(outputValue) } : {},
1223
1224
  ...secretsValue ? { secrets: secretsValue } : {}
1224
1225
  });
1225
1226
  yield* printOr(json, result, formatNetworkResult(result));
@@ -1237,10 +1238,10 @@ registerCliCommand(600, () => network);
1237
1238
  // src/cli/recording.ts
1238
1239
  import { Console as Console5, Effect as Effect7, Option as Option6 } from "effect";
1239
1240
  import { Argument as Argument3, Command as Command4, Flag as Flag5 } from "effect/cli";
1240
- import path4 from "node:path";
1241
+ import path3 from "node:path";
1241
1242
  var recordingStart = Command4.make("start", {
1242
1243
  outputPath: Argument3.String("output-path").pipe(Argument3.withDescription("Path to write the recording artifact; tabCapture requires .webm, CDP accepts .webm or .mp4")),
1243
- session: sessionFlag("Record the page for this Browse or CDP session id"),
1244
+ session: sessionFlag("Record the page for this browse or CDP session id"),
1244
1245
  tabId: tabIdFlag("Record this attached Chrome tab id"),
1245
1246
  mode: Flag5.String("mode").pipe(Flag5.optional, Flag5.withDescription("Recording mode: auto, tab-capture, or cdp. auto uses CDP for relay-owned tabs and tabCapture for user-owned tabs")),
1246
1247
  audio: Flag5.Boolean("audio").pipe(Flag5.withDefault(false), Flag5.withDescription("Include tab audio")),
@@ -1266,7 +1267,7 @@ var recordingStart = Command4.make("start", {
1266
1267
  yield* ensureCliRelayAndExtension();
1267
1268
  const target = yield* recordingTarget({ session, tabId });
1268
1269
  const modeValue = yield* parseRecordingModeOption(Option6.getOrUndefined(mode));
1269
- const resolvedOutputPath = path4.resolve(outputPath);
1270
+ const resolvedOutputPath = path3.resolve(outputPath);
1270
1271
  const result = yield* relay.recordingStart({
1271
1272
  ...target,
1272
1273
  outputPath: resolvedOutputPath,
@@ -1378,7 +1379,7 @@ var flightRecorderSaveLast = Command4.make("save-last", {
1378
1379
  yield* ensureCliRelay();
1379
1380
  const result = yield* relay.flightRecorderSaveLast({
1380
1381
  ...yield* recordingTarget({ session, tabId }),
1381
- outputPath: path4.resolve(outputPath),
1382
+ outputPath: path3.resolve(outputPath),
1382
1383
  ...Option6.isSome(durationMs) ? { durationMs: durationMs.value } : {}
1383
1384
  });
1384
1385
  yield* printOr(json, result, `Saved ${result.durationMs}ms flight recorder clip (${result.frameCount} frames) to ${result.path}`);
@@ -1405,23 +1406,23 @@ registerCliCommand(710, () => flightRecorder);
1405
1406
  import { Console as Console6, Effect as Effect8 } from "effect";
1406
1407
  import { Command as Command5, Flag as Flag6 } from "effect/cli";
1407
1408
  var serve = Command5.make("serve", {}, Effect8.fn("Cli.serve")(function* () {
1408
- const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect8.promise(() => Promise.all([import("./relay-cvhz2f0a.mjs"), import("./helpers-n4k4pdag.mjs")]));
1409
+ const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect8.promise(() => Promise.all([import("./relay-446cn6cs.mjs"), import("./helpers-d74qp3s1.mjs")]));
1409
1410
  const port = yield* portConfig;
1410
1411
  const additionalExtensionOrigins = parseAdditionalExtensionOrigins(yield* extensionOriginsConfig);
1411
1412
  yield* Effect8.scoped(Effect8.gen(function* () {
1412
1413
  const relay = yield* startRelay({ port, additionalExtensionOrigins });
1413
- yield* Console6.log(`Browse relay listening at ${relay.url}`);
1414
- yield* Console6.log(`Browse connects automatically while the browser runs. Run \`${cliCommand("status")}\` to check.`);
1414
+ yield* Console6.log(`browse relay listening at ${relay.url}`);
1415
+ yield* Console6.log(`browse connects automatically while the browser runs. Run \`${cliCommand("status")}\` to check.`);
1415
1416
  yield* Effect8.never;
1416
1417
  }));
1417
- })).pipe(Command5.withDescription("Start the local Browse relay"));
1418
+ })).pipe(Command5.withDescription("Start the local browse relay"));
1418
1419
  var relayRestart = Command5.make("restart", {
1419
1420
  force: Flag6.Boolean("force").pipe(Flag6.withDefault(false), Flag6.withDescription("End network captures and recordings (discarding them) and disconnect raw CDP clients instead of refusing to restart"))
1420
1421
  }, Effect8.fn("Cli.relayRestart")(function* ({ force }) {
1421
1422
  const relay = yield* Service;
1422
1423
  yield* Console6.error("Restarting the relay leaves browser tabs open but resets in-memory JavaScript state.");
1423
1424
  const readiness = yield* restartRelay({ relay, clientKind: "cli", force });
1424
- yield* Console6.log(`${readiness.started ? "Started" : "Reused concurrent replacement"} Browse relay at ${relay.endpoint} (${readiness.version.buildId})`);
1425
+ yield* Console6.log(`${readiness.started ? "Started" : "Reused concurrent replacement"} browse relay at ${relay.endpoint} (${readiness.version.buildId})`);
1425
1426
  })).pipe(Command5.withDescription("Explicitly drain and restart the managed relay using this installation"));
1426
1427
  var relay = Command5.make("relay").pipe(Command5.withDescription("Manage the local relay lifecycle"), Command5.withSubcommands([relayRestart]));
1427
1428
  registerCliCommand(100, () => serve);
@@ -1430,8 +1431,8 @@ registerCliCommand(110, () => relay);
1430
1431
  // src/cli/secrets.ts
1431
1432
  import { Console as Console7, Effect as Effect9, Option as Option7 } from "effect";
1432
1433
  import { Argument as Argument4, Command as Command6, Flag as Flag7 } from "effect/cli";
1433
- import path5 from "node:path";
1434
- import process2 from "node:process";
1434
+ import path4 from "node:path";
1435
+ import process3 from "node:process";
1435
1436
  var secretsStatus = Command6.make("status", {
1436
1437
  name: Argument4.String("name"),
1437
1438
  json: jsonFlag
@@ -1479,24 +1480,24 @@ var secretsRun = Command6.make("run", {
1479
1480
  name,
1480
1481
  command: executable,
1481
1482
  args,
1482
- cwd: path5.resolve(Option7.getOrElse(cwd, () => process2.cwd())),
1483
+ cwd: path4.resolve(Option7.getOrElse(cwd, () => process3.cwd())),
1483
1484
  ...Option7.isSome(timeoutMs) ? { timeoutMs: timeoutMs.value } : {}
1484
1485
  });
1485
1486
  yield* Effect9.sync(() => {
1486
1487
  if (result.stdout)
1487
- process2.stdout.write(result.stdout);
1488
+ process3.stdout.write(result.stdout);
1488
1489
  if (result.stderr)
1489
- process2.stderr.write(result.stderr);
1490
+ process3.stderr.write(result.stderr);
1490
1491
  if (result.stdoutTruncated || result.stderrTruncated)
1491
- process2.stderr.write(`
1492
+ process3.stderr.write(`
1492
1493
  Browse truncated child output.
1493
1494
  `);
1494
1495
  if (result.exitCode !== 0)
1495
- process2.exitCode = result.exitCode;
1496
+ process3.exitCode = result.exitCode;
1496
1497
  });
1497
1498
  })).pipe(Command6.withDescription("Run a command with profile values injected as BC_SECRET_* environment variables"));
1498
1499
  function readSecretValue(prompt) {
1499
- const input = process2.stdin;
1500
+ const input = process3.stdin;
1500
1501
  if (!input.isTTY) {
1501
1502
  return new Promise((resolve, reject) => {
1502
1503
  const chunks = [];
@@ -1506,13 +1507,13 @@ function readSecretValue(prompt) {
1506
1507
  });
1507
1508
  }
1508
1509
  return new Promise((resolve, reject) => {
1509
- process2.stderr.write(prompt);
1510
+ process3.stderr.write(prompt);
1510
1511
  let value = "";
1511
1512
  const finish = (result) => {
1512
1513
  input.setRawMode(false);
1513
1514
  input.pause();
1514
1515
  input.off("data", onData);
1515
- process2.stderr.write(`
1516
+ process3.stderr.write(`
1516
1517
  `);
1517
1518
  if (result instanceof Error)
1518
1519
  reject(result);
@@ -1587,20 +1588,20 @@ var deadboltConnect = Command6.make("connect", { json: jsonFlag }, Effect9.fn("C
1587
1588
  yield* emitJson({ connected: true, id: paired.id });
1588
1589
  return;
1589
1590
  }
1590
- yield* Console7.log(`Connected Browse to Deadbolt as client ${paired.id}.`);
1591
+ yield* Console7.log(`Connected browse to Deadbolt as client ${paired.id}.`);
1591
1592
  yield* Console7.log("Agents can use only the logins you allow, in Deadbolt: deadbolt agents allow <site> (narrow with --login, --fields, --expires), or deadbolt agents allow --all for every login");
1592
- })).pipe(Command6.withDescription("Pair Browse with Deadbolt (runs `deadbolt agents add-client browse`, which asks you to confirm) and store its client token (0600)"));
1593
+ })).pipe(Command6.withDescription("Pair browse with Deadbolt (runs `deadbolt agents add-client browse`, which asks you to confirm) and store its client token (0600)"));
1593
1594
  var deadboltDisconnect = Command6.make("disconnect", {}, Effect9.fn("Cli.deadboltDisconnect")(function* () {
1594
1595
  const result = yield* Effect9.try({
1595
1596
  try: () => unpair(),
1596
1597
  catch: (cause) => cause instanceof Error ? cause : new Error("Could not disconnect from Deadbolt")
1597
1598
  });
1598
1599
  if (!result.removed) {
1599
- yield* Console7.log("Browse isn't connected to Deadbolt");
1600
+ yield* Console7.log("browse isn't connected to Deadbolt");
1600
1601
  return;
1601
1602
  }
1602
1603
  yield* Console7.log(result.revoked ? "Disconnected: the client is removed in Deadbolt and its token deleted here." : "Deleted the client token here. Deadbolt didn't confirm removing the client: check `deadbolt agents clients`.");
1603
- })).pipe(Command6.withDescription("Remove Browse's Deadbolt client (in Deadbolt and here)"));
1604
+ })).pipe(Command6.withDescription("Remove browse's Deadbolt client (in Deadbolt and here)"));
1604
1605
  var deadboltStatus = Command6.make("status", { json: jsonFlag }, Effect9.fn("Cli.deadboltStatus")(function* ({ json }) {
1605
1606
  const client = readClient();
1606
1607
  const socket = socketPath();
@@ -1627,7 +1628,7 @@ var deadboltStatus = Command6.make("status", { json: jsonFlag }, Effect9.fn("Cli
1627
1628
  yield* Console7.log(`Deadbolt ${status.version ?? ""} (protocol ${status.protocol}) is ${status.unlocked ? "unlocked" : "locked: agent sign-ins are paused until you unlock it"}`);
1628
1629
  else if (status)
1629
1630
  yield* Console7.log(`Deadbolt isn't reachable: ${status.error}`);
1630
- })).pipe(Command6.withDescription("Show whether Browse is paired with Deadbolt and whether Deadbolt is reachable and unlocked"));
1631
+ })).pipe(Command6.withDescription("Show whether browse is paired with Deadbolt and whether Deadbolt is reachable and unlocked"));
1631
1632
  var deadbolt = Command6.make("deadbolt").pipe(Command6.withDescription("Let agents sign in with the Deadbolt logins you grant them, without seeing any value"), Command6.withSubcommands([deadboltConnect, deadboltDisconnect, deadboltStatus]));
1632
1633
  registerCliCommand(610, () => secrets);
1633
1634
  registerCliCommand(620, () => deadbolt);
@@ -1652,7 +1653,7 @@ var sessionNew = Command7.make("new", {
1652
1653
  });
1653
1654
  yield* store.write(result.id);
1654
1655
  yield* Console8.log(result.id);
1655
- })).pipe(Command7.withDescription("Create a Browse session and make it current"));
1656
+ })).pipe(Command7.withDescription("Create a browse session and make it current"));
1656
1657
  var sessionList = Command7.make("list", {
1657
1658
  json: jsonFlag
1658
1659
  }, Effect10.fn("Cli.sessionList")(function* ({ json }) {
@@ -1677,7 +1678,7 @@ var sessionList = Command7.make("list", {
1677
1678
  const allowed = item.allowedOrigins ? ` allow=${item.allowedOrigins.join(",")}` : "";
1678
1679
  return Console8.log(`${marker} ${item.id} ${page}${keys}${readOnly}${allowed}`);
1679
1680
  });
1680
- })).pipe(Command7.withDescription("List Browse sessions"));
1681
+ })).pipe(Command7.withDescription("List browse sessions"));
1681
1682
  var sessionCurrent = Command7.make("current", {}, Effect10.fn("Cli.sessionCurrent")(function* () {
1682
1683
  const store = yield* Service2;
1683
1684
  const current = yield* store.read;
@@ -1693,7 +1694,7 @@ var sessionUse = Command7.make("use", {
1693
1694
  })).pipe(Command7.withDescription("Set the current default session"));
1694
1695
  var sessionReset = Command7.make("reset", {
1695
1696
  id: Argument5.String("id").pipe(Argument5.optional),
1696
- session: sessionFlag("Reset this Browse session id")
1697
+ session: sessionFlag("Reset this browse session id")
1697
1698
  }, Effect10.fn("Cli.sessionReset")(function* ({ id, session }) {
1698
1699
  const relay = yield* Service;
1699
1700
  const sessionId = yield* resolvePositionalOrFlagSessionId(id, session);
@@ -1702,9 +1703,9 @@ var sessionReset = Command7.make("reset", {
1702
1703
  if (reset.stopped)
1703
1704
  yield* Console8.error(`Stopped first: ${describeStop(reset.stopped)}`);
1704
1705
  yield* Console8.log(reset.session.id);
1705
- })).pipe(Command7.withDescription("Reset a Browse session state and page"));
1706
+ })).pipe(Command7.withDescription("Reset a browse session state and page"));
1706
1707
  var sessionAdopt = Command7.make("adopt", {
1707
- session: sessionFlag("Adopt into this Browse session, creating it when it does not exist yet; omit to create a fresh readable id"),
1708
+ session: sessionFlag("Adopt into this browse session, creating it when it does not exist yet; omit to create a fresh readable id"),
1708
1709
  targetUrl: Flag8.String("target-url").pipe(Flag8.optional, Flag8.withDescription("Adopt the attached page whose URL contains this text")),
1709
1710
  targetIndex: Flag8.Int("target-index").pipe(Flag8.optional, Flag8.withDescription("Adopt the attached page at this zero-based target index")),
1710
1711
  tabId: tabIdFlag("Adopt the user's shared tab with this Chrome tab id (the tab= value in status)")
@@ -1735,7 +1736,7 @@ var sessionAdopt = Command7.make("adopt", {
1735
1736
  })).pipe(Command7.withDescription("Make an attached tab the session's default page"));
1736
1737
  var sessionDelete = Command7.make("delete", {
1737
1738
  id: Argument5.String("id").pipe(Argument5.optional),
1738
- session: sessionFlag("Delete this Browse session id")
1739
+ session: sessionFlag("Delete this browse session id")
1739
1740
  }, Effect10.fn("Cli.sessionDelete")(function* ({ id, session }) {
1740
1741
  const relay = yield* Service;
1741
1742
  const store = yield* Service2;
@@ -1749,7 +1750,7 @@ var sessionDelete = Command7.make("delete", {
1749
1750
  yield* store.clear;
1750
1751
  }
1751
1752
  yield* Console8.log(sessionId);
1752
- })).pipe(Command7.withDescription("Delete a Browse session"));
1753
+ })).pipe(Command7.withDescription("Delete a browse session"));
1753
1754
  var sessionAllow = Command7.make("allow", {
1754
1755
  session: sessionFlag(),
1755
1756
  origins: Argument5.String("origins").pipe(Argument5.variadic({ min: 0 }), Argument5.withDescription("Hosts or origins the session's tabs may load: example.com, *.example.com, https://app.example.com, http://localhost:3000")),
@@ -1769,7 +1770,7 @@ var sessionAllow = Command7.make("allow", {
1769
1770
  }
1770
1771
  yield* Console8.log(result.allowedOrigins ? `${result.id} may load: ${result.allowedOrigins.join(", ")}` : `${result.id} may load any site`);
1771
1772
  })).pipe(Command7.withDescription("Set the domain allowlist of a session (the current one by default)"));
1772
- var session = Command7.make("session").pipe(Command7.withDescription("Manage Browse sessions"), Command7.withSubcommands([
1773
+ var session = Command7.make("session").pipe(Command7.withDescription("Manage browse sessions"), Command7.withSubcommands([
1773
1774
  sessionNew,
1774
1775
  sessionList,
1775
1776
  sessionCurrent,
@@ -1780,7 +1781,7 @@ var session = Command7.make("session").pipe(Command7.withDescription("Manage Bro
1780
1781
  sessionAllow
1781
1782
  ]));
1782
1783
  var journal = Command7.make("journal", {
1783
- session: sessionFlag("Show the journal for this Browse session id"),
1784
+ session: sessionFlag("Show the journal for this browse session id"),
1784
1785
  limit: Flag8.Int("limit").pipe(Flag8.optional, Flag8.withDescription("Number of most recent entries to show, defaults to 20")),
1785
1786
  json: jsonFlag
1786
1787
  }, Effect10.fn("Cli.journal")(function* ({ session, limit, json }) {
@@ -1805,15 +1806,15 @@ var journal = Command7.make("journal", {
1805
1806
  yield* Effect10.forEach(entries, (entry) => {
1806
1807
  return Console8.log(formatJournalEntry(entry));
1807
1808
  });
1808
- })).pipe(Command7.withDescription("Show what agents did in a Browse session"));
1809
+ })).pipe(Command7.withDescription("Show what agents did in a browse session"));
1809
1810
  registerCliCommand(300, () => session);
1810
1811
  registerCliCommand(800, () => journal);
1811
1812
 
1812
1813
  // src/cli.ts
1813
- var packageRoot = path6.dirname(path6.dirname(fileURLToPath(import.meta.url)));
1814
- var opencodeBrowser = Command8.make("opencode-browser").pipe(Command8.withDescription("Control the user's existing browser through the Browse extension"), Command8.withSubcommands(buildRegisteredCliCommands({ packageRoot })));
1814
+ var packageRoot = path5.dirname(path5.dirname(fileURLToPath(import.meta.url)));
1815
+ var opencodeBrowser = Command8.make("opencode-browser").pipe(Command8.withDescription("Control the user's existing browser through the browse extension"), Command8.withSubcommands(buildRegisteredCliCommands({ packageRoot })));
1815
1816
  var mainLayer = Layer2.mergeAll(layerFetch, layer).pipe(Layer2.provideMerge(NodeServices.layer));
1816
- function runCli(rawArgs = process3.argv.slice(2)) {
1817
+ function runCli(rawArgs = process4.argv.slice(2)) {
1817
1818
  const cliArgs = hoistJsonFlag(rawArgs);
1818
1819
  const subcommand = cliArgs.argv.find((arg) => !arg.startsWith("-"));
1819
1820
  const commandName = subcommand ? `opencode-browser ${subcommand}` : "opencode-browser";
@@ -1844,7 +1845,7 @@ function runCli(rawArgs = process3.argv.slice(2)) {
1844
1845
  const quietJson = cliArgs.json && !askedForHelp;
1845
1846
  Command8.runWith(opencodeBrowser, { version: opencodeBrowserVersion2, renderErrors: !quietJson })(normalizeCliArguments(cliArgs.argv)).pipe(quietJson ? Effect11.provideService(Console9.Console, { ...globalThis.console, log: silent }) : (effect) => effect, Effect11.catchIf(CliError.isCliError, reportUsageError), Effect11.catch(reportFailure), Effect11.provide(mainLayer), NodeRuntime.runMain);
1846
1847
  }
1847
- if (process3.argv[1] && import.meta.url === pathToFileURL(process3.argv[1]).href) {
1848
+ if (process4.argv[1] && import.meta.url === pathToFileURL(process4.argv[1]).href && import.meta.url.endsWith("/cli.ts")) {
1848
1849
  runCli();
1849
1850
  }
1850
1851
  export {
package/dist/cli.mjs CHANGED
@@ -2,34 +2,39 @@
2
2
 
3
3
  // src/main.ts
4
4
  import path from "node:path";
5
- var embeddedVersion = "0.0.6-dev.20";
5
+ var embeddedVersion = "0.0.6-dev.21";
6
6
  var setupCommands = new Set(["install", "uninstall", "extension", "pair", "rollback", "set"]);
7
7
  var command = process.argv[2];
8
8
  var invokedAs = path.basename(process.argv[1] ?? "");
9
9
  if (command === "--version" || command === "-v") {
10
- const opencodeBrowserVersion = embeddedVersion ?? (await import("./version-gfpqxbzm.mjs")).opencodeBrowserVersion;
10
+ const opencodeBrowserVersion = embeddedVersion ?? (await import("./version-x7djen82.mjs")).opencodeBrowserVersion;
11
11
  process.stdout.write(`${opencodeBrowserVersion}
12
12
  `);
13
13
  } else if (invokedAs === "opencode-browser-mcp" || command === "mcp" && process.argv.length === 3) {
14
14
  const { NodeRuntime } = await import("@effect/platform-node");
15
- const { runMcpServer } = await import("./mcp-j9e2da4y.mjs");
15
+ const { runMcpServer } = await import("./mcp-qmq1yerr.mjs");
16
16
  runMcpServer.pipe(NodeRuntime.runMain);
17
+ } else if (command === "mcp" && globalThis.__OPENCODE_BROWSER_COMPILED__ && process.env.OPENCODE_BROWSER_MCP_DIRECT !== "1") {
18
+ const { runBinaryMcp } = await import("./supervisor-bvnx7xgg.mjs");
19
+ await runBinaryMcp(process.argv.slice(3));
17
20
  } else if (command === "runtime-install" || command === "runtime-switch") {
18
- const { runRuntimeInstall, runRuntimeSwitch } = await import("./runtime-update-baranjc5.mjs");
21
+ const { runRuntimeInstall, runRuntimeSwitch } = await import("./runtime-update-fj4s270v.mjs");
19
22
  await (command === "runtime-install" ? runRuntimeInstall : runRuntimeSwitch)(process.argv.slice(3));
20
23
  } else if (command === "update") {
21
- const { runUpdateCommand } = await import("./update-vkspb2rz.mjs");
24
+ const { runUpdateCommand } = await import("./update-38wp6pt4.mjs");
22
25
  await runUpdateCommand(process.argv.slice(3));
23
26
  } else if (command && setupCommands.has(command)) {
24
- const { runSetup } = await import("./setup-7shrgdza.mjs");
27
+ const { runSetup } = await import("./setup-atsf76r6.mjs");
25
28
  await runSetup(command, process.argv.slice(3));
26
29
  } else {
27
30
  if (!command || command === "--help" || command === "-h") {
28
31
  process.stdout.write(`SETUP
29
- install [--opencode <path>] Install Browse: choose agents for the browse MCP server, check which browsers
32
+ install [--opencode <path>] Install browse: choose agents for the browse MCP server, check which browsers
30
33
  have the extension and pair it (when none does, open its Chrome Web Store
31
34
  page, or from a checkout or a dev install show the folder to load unpacked,
32
35
  and wait for it)
36
+ --remote For a browser on another computer: open the relay to other computers and print
37
+ its address and a one-time pairing code instead of pairing a browser here
33
38
  --no-open Print the steps without opening anything or copying the path
34
39
  --no-wait Don't wait for the extension to be added or connect
35
40
  --wait-seconds <seconds> How long to wait for a connection (default 180 in a terminal, 90 otherwise)
@@ -55,9 +60,9 @@ if (command === "--version" || command === "-v") {
55
60
  `);
56
61
  }
57
62
  if (command === "status" && !process.argv.includes("--json")) {
58
- const { printSetupStatus } = await import("./setup-7shrgdza.mjs");
63
+ const { printSetupStatus } = await import("./setup-atsf76r6.mjs");
59
64
  printSetupStatus();
60
65
  }
61
- const { runCli } = await import("./cli-anqhds1e.mjs");
66
+ const { runCli } = await import("./cli-qcdv8aqh.mjs");
62
67
  runCli();
63
68
  }
@@ -31,7 +31,8 @@ import {
31
31
  isRestrictedTarget2,
32
32
  isRestrictedUrl2,
33
33
  dataUrlDocument2
34
- } from "./main-0nta0a2z.mjs";
34
+ } from "./main-qm2keaeb.mjs";
35
+ import"./main-3gthmkzw.mjs";
35
36
  export {
36
37
  HttpRouteError2 as HttpRouteError,
37
38
  chromeExtensionOriginForPath2 as chromeExtensionOriginForPath,