@opencode/browse 0.0.6-dev.19 → 0.0.6-dev.20
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/{cli-22fe7etn.mjs → cli-anqhds1e.mjs} +9 -9
- package/dist/cli.mjs +8 -8
- package/dist/{helpers-rta4d2as.mjs → helpers-n4k4pdag.mjs} +9 -9
- package/dist/{main-8a245rm1.mjs → main-0nta0a2z.mjs} +184 -177
- package/dist/{main-75rdz6bc.mjs → main-20ahaz2q.mjs} +1 -1
- package/dist/{main-2wrztakb.mjs → main-3rsfghef.mjs} +2 -2
- package/dist/{main-knahxbey.mjs → main-42qfr69q.mjs} +3 -3
- package/dist/main-arx3pfyn.mjs +4 -0
- package/dist/{main-xatp12cr.mjs → main-hywb9qbv.mjs} +2 -2
- package/dist/{main-yd50d95g.mjs → main-ma25hhqh.mjs} +1 -1
- package/dist/{main-90enpn5q.mjs → main-yd1d7qr1.mjs} +3 -3
- package/dist/{mcp-p0mcjvq9.mjs → mcp-j9e2da4y.mjs} +6 -6
- package/dist/{relay-tfvn856e.mjs → relay-cvhz2f0a.mjs} +4535 -4382
- package/dist/{runtime-update-pxbj49tf.mjs → runtime-update-baranjc5.mjs} +4 -4
- package/dist/{setup-y8pd11b8.mjs → setup-7shrgdza.mjs} +5 -5
- package/dist/{update-5fx8t344.mjs → update-vkspb2rz.mjs} +2 -2
- package/dist/{version-cjhq7cm9.mjs → version-gfpqxbzm.mjs} +1 -1
- package/package.json +1 -1
- package/dist/main-ts9jjqs8.mjs +0 -4
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
autoUpdateStatus,
|
|
9
9
|
extensionProtocolVersion,
|
|
10
10
|
extensionProtocolAdvice
|
|
11
|
-
} from "./main-
|
|
11
|
+
} from "./main-ma25hhqh.mjs";
|
|
12
12
|
import {
|
|
13
13
|
defaultPort2,
|
|
14
14
|
isValidSessionId2,
|
|
@@ -27,17 +27,17 @@ import {
|
|
|
27
27
|
ensureExtensionConnected,
|
|
28
28
|
stoppedRelayStatus,
|
|
29
29
|
statusCollections
|
|
30
|
-
} from "./main-
|
|
31
|
-
import"./main-
|
|
30
|
+
} from "./main-0nta0a2z.mjs";
|
|
31
|
+
import"./main-20ahaz2q.mjs";
|
|
32
32
|
import {
|
|
33
33
|
opencodeBrowserVersion2,
|
|
34
34
|
opencodeBrowserBuildId2
|
|
35
|
-
} from "./main-
|
|
35
|
+
} from "./main-arx3pfyn.mjs";
|
|
36
36
|
import {
|
|
37
37
|
updateJson2,
|
|
38
38
|
formatUpdateNotice2,
|
|
39
39
|
updateNotice2
|
|
40
|
-
} from "./main-
|
|
40
|
+
} from "./main-3rsfghef.mjs";
|
|
41
41
|
import {
|
|
42
42
|
settingKeys,
|
|
43
43
|
formatSettings,
|
|
@@ -50,12 +50,12 @@ import {
|
|
|
50
50
|
addSecret,
|
|
51
51
|
listSecrets,
|
|
52
52
|
removeSecret
|
|
53
|
-
} from "./main-
|
|
53
|
+
} from "./main-yd1d7qr1.mjs";
|
|
54
54
|
import {
|
|
55
55
|
defaultJournalBaseDir,
|
|
56
56
|
readJournalEntries,
|
|
57
57
|
formatJournalEntry
|
|
58
|
-
} from "./main-
|
|
58
|
+
} from "./main-42qfr69q.mjs";
|
|
59
59
|
|
|
60
60
|
// src/cli.ts
|
|
61
61
|
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
@@ -948,7 +948,7 @@ var status = Command.make("status", {
|
|
|
948
948
|
}
|
|
949
949
|
})).pipe(Command.withDescription("Show relay, extension, and target status"));
|
|
950
950
|
var mcp = Command.make("mcp", {}, Effect4.fn("Cli.mcp")(function* () {
|
|
951
|
-
const { runMcpServer } = yield* Effect4.promise(() => import("./mcp-
|
|
951
|
+
const { runMcpServer } = yield* Effect4.promise(() => import("./mcp-j9e2da4y.mjs"));
|
|
952
952
|
yield* runMcpServer;
|
|
953
953
|
})).pipe(Command.withDescription("Run the Browse MCP server over stdio"));
|
|
954
954
|
registerCliCommand(400, () => tabs);
|
|
@@ -1405,7 +1405,7 @@ registerCliCommand(710, () => flightRecorder);
|
|
|
1405
1405
|
import { Console as Console6, Effect as Effect8 } from "effect";
|
|
1406
1406
|
import { Command as Command5, Flag as Flag6 } from "effect/cli";
|
|
1407
1407
|
var serve = Command5.make("serve", {}, Effect8.fn("Cli.serve")(function* () {
|
|
1408
|
-
const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect8.promise(() => Promise.all([import("./relay-
|
|
1408
|
+
const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect8.promise(() => Promise.all([import("./relay-cvhz2f0a.mjs"), import("./helpers-n4k4pdag.mjs")]));
|
|
1409
1409
|
const port = yield* portConfig;
|
|
1410
1410
|
const additionalExtensionOrigins = parseAdditionalExtensionOrigins(yield* extensionOriginsConfig);
|
|
1411
1411
|
yield* Effect8.scoped(Effect8.gen(function* () {
|
package/dist/cli.mjs
CHANGED
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
var embeddedVersion = "0.0.6-dev.
|
|
5
|
+
var embeddedVersion = "0.0.6-dev.20";
|
|
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-
|
|
10
|
+
const opencodeBrowserVersion = embeddedVersion ?? (await import("./version-gfpqxbzm.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-
|
|
15
|
+
const { runMcpServer } = await import("./mcp-j9e2da4y.mjs");
|
|
16
16
|
runMcpServer.pipe(NodeRuntime.runMain);
|
|
17
17
|
} else if (command === "runtime-install" || command === "runtime-switch") {
|
|
18
|
-
const { runRuntimeInstall, runRuntimeSwitch } = await import("./runtime-update-
|
|
18
|
+
const { runRuntimeInstall, runRuntimeSwitch } = await import("./runtime-update-baranjc5.mjs");
|
|
19
19
|
await (command === "runtime-install" ? runRuntimeInstall : runRuntimeSwitch)(process.argv.slice(3));
|
|
20
20
|
} else if (command === "update") {
|
|
21
|
-
const { runUpdateCommand } = await import("./update-
|
|
21
|
+
const { runUpdateCommand } = await import("./update-vkspb2rz.mjs");
|
|
22
22
|
await runUpdateCommand(process.argv.slice(3));
|
|
23
23
|
} else if (command && setupCommands.has(command)) {
|
|
24
|
-
const { runSetup } = await import("./setup-
|
|
24
|
+
const { runSetup } = await import("./setup-7shrgdza.mjs");
|
|
25
25
|
await runSetup(command, process.argv.slice(3));
|
|
26
26
|
} else {
|
|
27
27
|
if (!command || command === "--help" || command === "-h") {
|
|
@@ -55,9 +55,9 @@ if (command === "--version" || command === "-v") {
|
|
|
55
55
|
`);
|
|
56
56
|
}
|
|
57
57
|
if (command === "status" && !process.argv.includes("--json")) {
|
|
58
|
-
const { printSetupStatus } = await import("./setup-
|
|
58
|
+
const { printSetupStatus } = await import("./setup-7shrgdza.mjs");
|
|
59
59
|
printSetupStatus();
|
|
60
60
|
}
|
|
61
|
-
const { runCli } = await import("./cli-
|
|
61
|
+
const { runCli } = await import("./cli-anqhds1e.mjs");
|
|
62
62
|
runCli();
|
|
63
63
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
defaultHost2,
|
|
3
|
-
defaultPort2,
|
|
4
|
-
stableUnpackedExtensionOrigin2,
|
|
5
|
-
chromeExtensionOriginForPath2,
|
|
6
|
-
parseAdditionalExtensionOrigins2,
|
|
7
2
|
HttpRouteError2,
|
|
8
3
|
formatHostForUrl2,
|
|
9
|
-
validateHostHeader2,
|
|
10
|
-
validateBrowserFetchSite2,
|
|
11
|
-
validateWebSocketOrigin2,
|
|
12
4
|
listenHttpServer2,
|
|
13
5
|
closeHttpServer2,
|
|
14
6
|
closeWebSocketServer2,
|
|
15
7
|
logCloseError2,
|
|
16
8
|
sendJson2,
|
|
17
9
|
readJsonBody2,
|
|
10
|
+
stableUnpackedExtensionOrigin2,
|
|
11
|
+
chromeExtensionOriginForPath2,
|
|
12
|
+
parseAdditionalExtensionOrigins2,
|
|
13
|
+
validateHostHeader2,
|
|
14
|
+
validateBrowserFetchSite2,
|
|
15
|
+
validateWebSocketOrigin2,
|
|
16
|
+
defaultHost2,
|
|
17
|
+
defaultPort2,
|
|
18
18
|
optionalSessionId2,
|
|
19
19
|
isValidSessionId2,
|
|
20
20
|
requiredSessionId2,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
isRestrictedTarget2,
|
|
32
32
|
isRestrictedUrl2,
|
|
33
33
|
dataUrlDocument2
|
|
34
|
-
} from "./main-
|
|
34
|
+
} from "./main-0nta0a2z.mjs";
|
|
35
35
|
export {
|
|
36
36
|
HttpRouteError2 as HttpRouteError,
|
|
37
37
|
chromeExtensionOriginForPath2 as chromeExtensionOriginForPath,
|
|
@@ -6,17 +6,19 @@ import {
|
|
|
6
6
|
extensionReconnectAlarmPeriodMs,
|
|
7
7
|
extensionProtocolAdvice,
|
|
8
8
|
parseJsonObject
|
|
9
|
-
} from "./main-
|
|
9
|
+
} from "./main-ma25hhqh.mjs";
|
|
10
10
|
import {
|
|
11
11
|
relayAuthorization
|
|
12
|
-
} from "./main-
|
|
12
|
+
} from "./main-20ahaz2q.mjs";
|
|
13
13
|
import {
|
|
14
14
|
opencodeBrowserBuildId2
|
|
15
|
-
} from "./main-
|
|
15
|
+
} from "./main-arx3pfyn.mjs";
|
|
16
16
|
|
|
17
17
|
// src/relay/helpers.ts
|
|
18
|
-
import
|
|
19
|
-
|
|
18
|
+
import { Option, Predicate, Schema as Schema3 } from "effect";
|
|
19
|
+
|
|
20
|
+
// src/relay/http.ts
|
|
21
|
+
import { Effect, Schema as Schema2 } from "effect";
|
|
20
22
|
|
|
21
23
|
// src/relay/schema.ts
|
|
22
24
|
import { Schema } from "effect";
|
|
@@ -524,37 +526,7 @@ var ErrorEnvelope = Schema.Struct({
|
|
|
524
526
|
code: Schema.optionalKey(RelayErrorCode)
|
|
525
527
|
});
|
|
526
528
|
|
|
527
|
-
// src/relay/
|
|
528
|
-
var defaultHost2 = "127.0.0.1";
|
|
529
|
-
var defaultPort2 = 19988;
|
|
530
|
-
var stableUnpackedExtensionOrigin2 = `chrome-extension://${unpackedExtensionId}`;
|
|
531
|
-
function chromeExtensionOriginForPath2(extensionPath, platform = process.platform) {
|
|
532
|
-
const normalizedPath = platform === "win32" && /^[a-z]:/.test(extensionPath) ? extensionPath.charAt(0).toUpperCase() + extensionPath.slice(1) : extensionPath;
|
|
533
|
-
const pathBytes = platform === "win32" ? Buffer.from(normalizedPath, "utf16le") : normalizedPath;
|
|
534
|
-
const digest = crypto.createHash("sha256").update(pathBytes).digest();
|
|
535
|
-
let extensionId = "";
|
|
536
|
-
for (const byte of digest.subarray(0, 16)) {
|
|
537
|
-
extensionId += String.fromCharCode(97 + (byte >> 4), 97 + (byte & 15));
|
|
538
|
-
}
|
|
539
|
-
return `chrome-extension://${extensionId}`;
|
|
540
|
-
}
|
|
541
|
-
var chromeExtensionOriginPattern = /^chrome-extension:\/\/[a-p]+$/;
|
|
542
|
-
function parseAdditionalExtensionOrigins2(raw) {
|
|
543
|
-
if (!raw) {
|
|
544
|
-
return [];
|
|
545
|
-
}
|
|
546
|
-
const seen = new Set;
|
|
547
|
-
const origins = [];
|
|
548
|
-
for (const token of raw.split(/[\s,]+/)) {
|
|
549
|
-
const value = token.trim();
|
|
550
|
-
if (!value || !chromeExtensionOriginPattern.test(value) || seen.has(value)) {
|
|
551
|
-
continue;
|
|
552
|
-
}
|
|
553
|
-
seen.add(value);
|
|
554
|
-
origins.push(value);
|
|
555
|
-
}
|
|
556
|
-
return origins;
|
|
557
|
-
}
|
|
529
|
+
// src/relay/http.ts
|
|
558
530
|
var maxCliBodyBytes = 1e6;
|
|
559
531
|
|
|
560
532
|
class HttpRouteError2 extends Schema2.TaggedError()("HttpApi.HttpRouteError", { message: Schema2.String, status: Schema2.Number, code: RelayErrorCode }) {
|
|
@@ -565,98 +537,6 @@ function formatHostForUrl2(host) {
|
|
|
565
537
|
}
|
|
566
538
|
return host;
|
|
567
539
|
}
|
|
568
|
-
function validateHostHeader2(options) {
|
|
569
|
-
const parsed = parseHostHeader(options.hostHeader);
|
|
570
|
-
if (!parsed) {
|
|
571
|
-
return "Invalid Host header";
|
|
572
|
-
}
|
|
573
|
-
if (parsed.port !== undefined && parsed.port !== options.port) {
|
|
574
|
-
return "Invalid Host header port";
|
|
575
|
-
}
|
|
576
|
-
const allowedHosts = new Set(["localhost", "127.0.0.1", "::1", normalizeHostname(options.host)]);
|
|
577
|
-
if (!allowedHosts.has(parsed.hostname)) {
|
|
578
|
-
return "Invalid Host header";
|
|
579
|
-
}
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
582
|
-
function validateBrowserFetchSite2(request) {
|
|
583
|
-
const secFetchSite = request.headers["sec-fetch-site"];
|
|
584
|
-
const value = Array.isArray(secFetchSite) ? secFetchSite[0] : secFetchSite;
|
|
585
|
-
if (!value || value === "same-origin" || value === "none") {
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
return "Cross-origin browser requests are not allowed";
|
|
589
|
-
}
|
|
590
|
-
function validateWebSocketOrigin2(options) {
|
|
591
|
-
if (!options.origin) {
|
|
592
|
-
return options.requireChromeExtension ? "Extension WebSocket origin is required" : undefined;
|
|
593
|
-
}
|
|
594
|
-
if (options.origin === stableUnpackedExtensionOrigin2 || options.additionalChromeExtensionOrigins?.has(options.origin)) {
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
if (options.requireChromeExtension) {
|
|
598
|
-
return "Extension WebSocket origin is not allowed";
|
|
599
|
-
}
|
|
600
|
-
return "WebSocket origin is not allowed";
|
|
601
|
-
}
|
|
602
|
-
function normalizeHostname(host) {
|
|
603
|
-
const value = host.trim().toLowerCase();
|
|
604
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
605
|
-
return value.slice(1, -1);
|
|
606
|
-
}
|
|
607
|
-
return value;
|
|
608
|
-
}
|
|
609
|
-
function parseHostHeader(hostHeader) {
|
|
610
|
-
const value = hostHeader?.trim().toLowerCase();
|
|
611
|
-
if (!value) {
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
if (value.startsWith("[")) {
|
|
615
|
-
const closingBracket = value.indexOf("]");
|
|
616
|
-
if (closingBracket === -1) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
const hostname = value.slice(1, closingBracket);
|
|
620
|
-
const rest = value.slice(closingBracket + 1);
|
|
621
|
-
if (!hostname) {
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
if (!rest) {
|
|
625
|
-
return { hostname };
|
|
626
|
-
}
|
|
627
|
-
if (!rest.startsWith(":")) {
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
const port = parsePort(rest.slice(1));
|
|
631
|
-
return port === undefined ? undefined : { hostname, port };
|
|
632
|
-
}
|
|
633
|
-
if (value === "::1") {
|
|
634
|
-
return { hostname: "::1" };
|
|
635
|
-
}
|
|
636
|
-
const colonCount = value.split(":").length - 1;
|
|
637
|
-
if (colonCount > 1) {
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
if (colonCount === 0) {
|
|
641
|
-
return { hostname: value };
|
|
642
|
-
}
|
|
643
|
-
const [hostname, portText] = value.split(":");
|
|
644
|
-
if (!hostname || portText === undefined) {
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
const port = parsePort(portText);
|
|
648
|
-
return port === undefined ? undefined : { hostname, port };
|
|
649
|
-
}
|
|
650
|
-
function parsePort(value) {
|
|
651
|
-
if (!/^\d+$/.test(value)) {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
const port = Number(value);
|
|
655
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
return port;
|
|
659
|
-
}
|
|
660
540
|
function listenHttpServer2(options) {
|
|
661
541
|
return Effect.callback((resume) => {
|
|
662
542
|
const onError = (error) => {
|
|
@@ -791,22 +671,149 @@ function readJsonBody2(request) {
|
|
|
791
671
|
});
|
|
792
672
|
});
|
|
793
673
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
674
|
+
|
|
675
|
+
// src/relay/origins.ts
|
|
676
|
+
import crypto from "node:crypto";
|
|
677
|
+
var stableUnpackedExtensionOrigin2 = `chrome-extension://${unpackedExtensionId}`;
|
|
678
|
+
function chromeExtensionOriginForPath2(extensionPath, platform = process.platform) {
|
|
679
|
+
const normalizedPath = platform === "win32" && /^[a-z]:/.test(extensionPath) ? extensionPath.charAt(0).toUpperCase() + extensionPath.slice(1) : extensionPath;
|
|
680
|
+
const pathBytes = platform === "win32" ? Buffer.from(normalizedPath, "utf16le") : normalizedPath;
|
|
681
|
+
const digest = crypto.createHash("sha256").update(pathBytes).digest();
|
|
682
|
+
let extensionId = "";
|
|
683
|
+
for (const byte of digest.subarray(0, 16)) {
|
|
684
|
+
extensionId += String.fromCharCode(97 + (byte >> 4), 97 + (byte & 15));
|
|
685
|
+
}
|
|
686
|
+
return `chrome-extension://${extensionId}`;
|
|
687
|
+
}
|
|
688
|
+
var chromeExtensionOriginPattern = /^chrome-extension:\/\/[a-p]+$/;
|
|
689
|
+
function parseAdditionalExtensionOrigins2(raw) {
|
|
690
|
+
if (!raw) {
|
|
691
|
+
return [];
|
|
692
|
+
}
|
|
693
|
+
const seen = new Set;
|
|
694
|
+
const origins = [];
|
|
695
|
+
for (const token of raw.split(/[\s,]+/)) {
|
|
696
|
+
const value = token.trim();
|
|
697
|
+
if (!value || !chromeExtensionOriginPattern.test(value) || seen.has(value)) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
seen.add(value);
|
|
701
|
+
origins.push(value);
|
|
702
|
+
}
|
|
703
|
+
return origins;
|
|
704
|
+
}
|
|
705
|
+
function validateHostHeader2(options) {
|
|
706
|
+
const parsed = parseHostHeader(options.hostHeader);
|
|
707
|
+
if (!parsed) {
|
|
708
|
+
return "Invalid Host header";
|
|
709
|
+
}
|
|
710
|
+
if (parsed.port !== undefined && parsed.port !== options.port) {
|
|
711
|
+
return "Invalid Host header port";
|
|
712
|
+
}
|
|
713
|
+
const allowedHosts = new Set(["localhost", "127.0.0.1", "::1", normalizeHostname(options.host)]);
|
|
714
|
+
if (!allowedHosts.has(parsed.hostname)) {
|
|
715
|
+
return "Invalid Host header";
|
|
716
|
+
}
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
function validateBrowserFetchSite2(request) {
|
|
720
|
+
const secFetchSite = request.headers["sec-fetch-site"];
|
|
721
|
+
const value = Array.isArray(secFetchSite) ? secFetchSite[0] : secFetchSite;
|
|
722
|
+
if (!value || value === "same-origin" || value === "none") {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
return "Cross-origin browser requests are not allowed";
|
|
726
|
+
}
|
|
727
|
+
function validateWebSocketOrigin2(options) {
|
|
728
|
+
if (!options.origin) {
|
|
729
|
+
return options.requireChromeExtension ? "Extension WebSocket origin is required" : undefined;
|
|
730
|
+
}
|
|
731
|
+
if (options.origin === stableUnpackedExtensionOrigin2 || options.additionalChromeExtensionOrigins?.has(options.origin)) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
if (options.requireChromeExtension) {
|
|
735
|
+
return "Extension WebSocket origin is not allowed";
|
|
736
|
+
}
|
|
737
|
+
return "WebSocket origin is not allowed";
|
|
738
|
+
}
|
|
739
|
+
function normalizeHostname(host) {
|
|
740
|
+
const value = host.trim().toLowerCase();
|
|
741
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
742
|
+
return value.slice(1, -1);
|
|
743
|
+
}
|
|
744
|
+
return value;
|
|
745
|
+
}
|
|
746
|
+
function parseHostHeader(hostHeader) {
|
|
747
|
+
const value = hostHeader?.trim().toLowerCase();
|
|
748
|
+
if (!value) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (value.startsWith("[")) {
|
|
752
|
+
const closingBracket = value.indexOf("]");
|
|
753
|
+
if (closingBracket === -1) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const hostname = value.slice(1, closingBracket);
|
|
757
|
+
const rest = value.slice(closingBracket + 1);
|
|
758
|
+
if (!hostname) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (!rest) {
|
|
762
|
+
return { hostname };
|
|
763
|
+
}
|
|
764
|
+
if (!rest.startsWith(":")) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
const port = parsePort(rest.slice(1));
|
|
768
|
+
return port === undefined ? undefined : { hostname, port };
|
|
769
|
+
}
|
|
770
|
+
if (value === "::1") {
|
|
771
|
+
return { hostname: "::1" };
|
|
772
|
+
}
|
|
773
|
+
const colonCount = value.split(":").length - 1;
|
|
774
|
+
if (colonCount > 1) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (colonCount === 0) {
|
|
778
|
+
return { hostname: value };
|
|
779
|
+
}
|
|
780
|
+
const [hostname, portText] = value.split(":");
|
|
781
|
+
if (!hostname || portText === undefined) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
const port = parsePort(portText);
|
|
785
|
+
return port === undefined ? undefined : { hostname, port };
|
|
786
|
+
}
|
|
787
|
+
function parsePort(value) {
|
|
788
|
+
if (!/^\d+$/.test(value)) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const port = Number(value);
|
|
792
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
return port;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// src/relay/helpers.ts
|
|
799
|
+
var defaultHost2 = "127.0.0.1";
|
|
800
|
+
var defaultPort2 = 19988;
|
|
801
|
+
var RawTargetSelection = Schema3.Struct({
|
|
802
|
+
urlIncludes: Schema3.optionalKey(Schema3.String),
|
|
803
|
+
index: Schema3.optionalKey(Schema3.Int.check(Schema3.isGreaterThanOrEqualTo(0)))
|
|
797
804
|
});
|
|
798
|
-
var decodeRawTargetSelection =
|
|
799
|
-
var RawTargetInfo =
|
|
800
|
-
targetId:
|
|
801
|
-
type:
|
|
802
|
-
title:
|
|
803
|
-
url:
|
|
804
|
-
canAccessOpener:
|
|
805
|
-
browserContextId:
|
|
806
|
-
openerId:
|
|
807
|
-
parentFrameId:
|
|
805
|
+
var decodeRawTargetSelection = Schema3.decodeUnknownOption(RawTargetSelection);
|
|
806
|
+
var RawTargetInfo = Schema3.Struct({
|
|
807
|
+
targetId: Schema3.String,
|
|
808
|
+
type: Schema3.Literals(["page", "iframe", "worker"]),
|
|
809
|
+
title: Schema3.optionalKey(Schema3.String),
|
|
810
|
+
url: Schema3.String,
|
|
811
|
+
canAccessOpener: Schema3.optionalKey(Schema3.Boolean),
|
|
812
|
+
browserContextId: Schema3.optionalKey(Schema3.String),
|
|
813
|
+
openerId: Schema3.optionalKey(Schema3.String),
|
|
814
|
+
parentFrameId: Schema3.optionalKey(Schema3.String)
|
|
808
815
|
});
|
|
809
|
-
var decodeRawTargetInfo =
|
|
816
|
+
var decodeRawTargetInfo = Schema3.decodeUnknownOption(RawTargetInfo);
|
|
810
817
|
function optionalSessionId2(value) {
|
|
811
818
|
if (!Predicate.isString(value) || !value.trim()) {
|
|
812
819
|
return;
|
|
@@ -947,7 +954,7 @@ async function dataUrlDocument2(url) {
|
|
|
947
954
|
}
|
|
948
955
|
|
|
949
956
|
// src/relay/lifecycle.ts
|
|
950
|
-
import { Config as Config2, Effect as Effect3, Result, Schedule, Schema as
|
|
957
|
+
import { Config as Config2, Effect as Effect3, Result, Schedule, Schema as Schema5 } from "effect";
|
|
951
958
|
import { spawn } from "node:child_process";
|
|
952
959
|
import crypto2 from "node:crypto";
|
|
953
960
|
import path from "node:path";
|
|
@@ -956,52 +963,52 @@ import { fileURLToPath } from "node:url";
|
|
|
956
963
|
|
|
957
964
|
// src/relay/client.ts
|
|
958
965
|
import { NodeHttpClient } from "@effect/platform-node";
|
|
959
|
-
import { Config, Context, Effect as Effect2, Layer, Option as Option2, Schema as
|
|
966
|
+
import { Config, Context, Effect as Effect2, Layer, Option as Option2, Schema as Schema4 } from "effect";
|
|
960
967
|
import { HttpClient, HttpClientRequest } from "effect/http";
|
|
961
968
|
var portConfig = Config.Int("OPENCODE_BROWSER_PORT").pipe(Config.withDefault(defaultPort2));
|
|
962
969
|
var extensionOriginsConfig = Config.String("OPENCODE_BROWSER_EXTENSION_ORIGINS").pipe(Config.withDefault(""));
|
|
963
970
|
var endpointForPort = (port) => `http://127.0.0.1:${port}`;
|
|
964
971
|
|
|
965
|
-
class RelayUnreachable extends
|
|
966
|
-
message:
|
|
967
|
-
endpoint:
|
|
968
|
-
path:
|
|
969
|
-
cause:
|
|
972
|
+
class RelayUnreachable extends Schema4.TaggedError()("RelayClient.RelayUnreachable", {
|
|
973
|
+
message: Schema4.String,
|
|
974
|
+
endpoint: Schema4.String,
|
|
975
|
+
path: Schema4.String,
|
|
976
|
+
cause: Schema4.Defect()
|
|
970
977
|
}) {
|
|
971
978
|
}
|
|
972
979
|
|
|
973
|
-
class RelayRejected extends
|
|
974
|
-
message:
|
|
975
|
-
status:
|
|
976
|
-
path:
|
|
977
|
-
code:
|
|
980
|
+
class RelayRejected extends Schema4.TaggedError()("RelayClient.RelayRejected", {
|
|
981
|
+
message: Schema4.String,
|
|
982
|
+
status: Schema4.Number,
|
|
983
|
+
path: Schema4.String,
|
|
984
|
+
code: Schema4.optionalKey(RelayErrorCode)
|
|
978
985
|
}) {
|
|
979
986
|
}
|
|
980
987
|
|
|
981
|
-
class RelayDecodeFailed extends
|
|
982
|
-
message:
|
|
983
|
-
path:
|
|
984
|
-
cause:
|
|
988
|
+
class RelayDecodeFailed extends Schema4.TaggedError()("RelayClient.RelayDecodeFailed", {
|
|
989
|
+
message: Schema4.String,
|
|
990
|
+
path: Schema4.String,
|
|
991
|
+
cause: Schema4.Defect()
|
|
985
992
|
}) {
|
|
986
993
|
}
|
|
987
994
|
|
|
988
|
-
class RelayEncodeFailed extends
|
|
989
|
-
message:
|
|
990
|
-
path:
|
|
991
|
-
cause:
|
|
995
|
+
class RelayEncodeFailed extends Schema4.TaggedError()("RelayClient.RelayEncodeFailed", {
|
|
996
|
+
message: Schema4.String,
|
|
997
|
+
path: Schema4.String,
|
|
998
|
+
cause: Schema4.Defect()
|
|
992
999
|
}) {
|
|
993
1000
|
}
|
|
994
1001
|
|
|
995
|
-
class RelayConfigInvalid extends
|
|
996
|
-
message:
|
|
997
|
-
cause:
|
|
1002
|
+
class RelayConfigInvalid extends Schema4.TaggedError()("RelayClient.RelayConfigInvalid", {
|
|
1003
|
+
message: Schema4.String,
|
|
1004
|
+
cause: Schema4.Defect()
|
|
998
1005
|
}) {
|
|
999
1006
|
}
|
|
1000
1007
|
|
|
1001
1008
|
class Service extends Context.Service()("opencode-browser-cli/RelayClient") {
|
|
1002
1009
|
}
|
|
1003
|
-
var decodeErrorEnvelope =
|
|
1004
|
-
var decodeErrorMessage =
|
|
1010
|
+
var decodeErrorEnvelope = Schema4.decodeUnknownOption(ErrorEnvelope);
|
|
1011
|
+
var decodeErrorMessage = Schema4.decodeUnknownOption(Schema4.Struct({ error: Schema4.String }));
|
|
1005
1012
|
var make = Effect2.fn("RelayClient.make")(function* (options) {
|
|
1006
1013
|
const port = yield* portConfig.pipe(Effect2.mapError((cause) => new RelayConfigInvalid({
|
|
1007
1014
|
message: `Invalid OPENCODE_BROWSER_PORT configuration: ${cause.message}`,
|
|
@@ -1025,7 +1032,7 @@ var make = Effect2.fn("RelayClient.make")(function* (options) {
|
|
|
1025
1032
|
...Option2.isSome(envelope) && envelope.value.code ? { code: envelope.value.code } : {}
|
|
1026
1033
|
}));
|
|
1027
1034
|
}
|
|
1028
|
-
return
|
|
1035
|
+
return Schema4.decodeUnknownEffect(schema)(body).pipe(Effect2.mapError((cause) => new RelayDecodeFailed({
|
|
1029
1036
|
message: `Relay response for ${path} did not match the expected shape: ${cause.message}`,
|
|
1030
1037
|
path,
|
|
1031
1038
|
cause
|
|
@@ -1136,19 +1143,19 @@ function shouldWaitForExtensionReconnect(readiness) {
|
|
|
1136
1143
|
class RelayStillRunning extends Error {
|
|
1137
1144
|
}
|
|
1138
1145
|
|
|
1139
|
-
class RelayStartFailed extends
|
|
1140
|
-
message:
|
|
1141
|
-
endpoint:
|
|
1142
|
-
cause:
|
|
1146
|
+
class RelayStartFailed extends Schema5.TaggedError()("RelayLifecycle.RelayStartFailed", {
|
|
1147
|
+
message: Schema5.String,
|
|
1148
|
+
endpoint: Schema5.String,
|
|
1149
|
+
cause: Schema5.Defect()
|
|
1143
1150
|
}) {
|
|
1144
1151
|
}
|
|
1145
1152
|
|
|
1146
|
-
class ExtensionDisconnected extends
|
|
1153
|
+
class ExtensionDisconnected extends Schema5.TaggedError()("RelayLifecycle.ExtensionDisconnected", { message: Schema5.String, needsPairing: Schema5.optionalKey(Schema5.Boolean) }) {
|
|
1147
1154
|
}
|
|
1148
1155
|
|
|
1149
|
-
class ExtensionProtocolIncompatible extends
|
|
1150
|
-
message:
|
|
1151
|
-
protocolVersion:
|
|
1156
|
+
class ExtensionProtocolIncompatible extends Schema5.TaggedError()("RelayLifecycle.ExtensionProtocolIncompatible", {
|
|
1157
|
+
message: Schema5.String,
|
|
1158
|
+
protocolVersion: Schema5.NullOr(Schema5.Number)
|
|
1152
1159
|
}) {
|
|
1153
1160
|
}
|
|
1154
1161
|
function supersededRuntime() {
|
|
@@ -1424,4 +1431,4 @@ function isRelayStartingOrUnreachable(error) {
|
|
|
1424
1431
|
return isRelayStarting(error) || isRelayUnreachable(error);
|
|
1425
1432
|
}
|
|
1426
1433
|
|
|
1427
|
-
export { ExecuteRequest, SessionAdoptRequest, SessionNewRequest, SessionEnsureRequest, SessionIdRequest, SessionAllowlistRequest, AuthenticatedJsonRequest, AuthenticatedJsonOutcome, RelayShutdownRequest, NetworkStartRequest, NetworkSessionRequest, NetworkStopRequest, DeadboltLoginsRequest, AuthProfileRequest, AuthRefreshRequest, AuthRunRequest, RecordingTargetRequest, RecordingStartRequest, FlightRecorderStartRequest, FlightRecorderSaveRequest,
|
|
1434
|
+
export { ExecuteRequest, SessionAdoptRequest, SessionNewRequest, SessionEnsureRequest, SessionIdRequest, SessionAllowlistRequest, AuthenticatedJsonRequest, AuthenticatedJsonOutcome, RelayShutdownRequest, NetworkStartRequest, NetworkSessionRequest, NetworkStopRequest, DeadboltLoginsRequest, AuthProfileRequest, AuthRefreshRequest, AuthRunRequest, RecordingTargetRequest, RecordingStartRequest, FlightRecorderStartRequest, FlightRecorderSaveRequest, HttpRouteError2, formatHostForUrl2, listenHttpServer2, closeHttpServer2, closeWebSocketServer2, logCloseError2, sendJson2, readJsonBody2, stableUnpackedExtensionOrigin2, chromeExtensionOriginForPath2, parseAdditionalExtensionOrigins2, validateHostHeader2, validateBrowserFetchSite2, validateWebSocketOrigin2, defaultHost2, defaultPort2, optionalSessionId2, isValidSessionId2, requiredSessionId2, parseTargetSelection2, generateSessionId2, sendCdpResponse2, sendCdpEvent2, getObject2, getString2, getNumber2, getIdText2, headerValue2, getTargetInfo2, isRestrictedTarget2, isRestrictedUrl2, dataUrlDocument2, portConfig, extensionOriginsConfig, endpointForPort, RelayUnreachable, RelayRejected, Service, layerFetch, layerFetchMcp, shouldWaitForExtensionReconnect, relayBuildProblem, ensureRelay, restartRelay, extensionReconnectWaitMs, ensureExtensionConnected, stoppedRelayStatus, statusCollections, startManagedRelay };
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
npmRuntime,
|
|
7
7
|
autoUpdateStatus,
|
|
8
8
|
unpackedReloadAdvice
|
|
9
|
-
} from "./main-
|
|
9
|
+
} from "./main-ma25hhqh.mjs";
|
|
10
10
|
|
|
11
11
|
// src/update.ts
|
|
12
12
|
import { execFile, spawnSync } from "node:child_process";
|
|
@@ -312,7 +312,7 @@ function runUpdate(args, deps) {
|
|
|
312
312
|
async function runUpdateCommand2(args) {
|
|
313
313
|
const log = (line) => process.stdout.write(line + `
|
|
314
314
|
`);
|
|
315
|
-
const { runNpmUpdate } = await import("./runtime-update-
|
|
315
|
+
const { runNpmUpdate } = await import("./runtime-update-baranjc5.mjs");
|
|
316
316
|
if (await runNpmUpdate(args))
|
|
317
317
|
return;
|
|
318
318
|
if (args.includes("--check")) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isNodeError
|
|
3
|
-
} from "./main-
|
|
3
|
+
} from "./main-20ahaz2q.mjs";
|
|
4
4
|
import {
|
|
5
5
|
dataRoot
|
|
6
|
-
} from "./main-
|
|
6
|
+
} from "./main-ma25hhqh.mjs";
|
|
7
7
|
import {
|
|
8
8
|
isValidSessionId2
|
|
9
|
-
} from "./main-
|
|
9
|
+
} from "./main-0nta0a2z.mjs";
|
|
10
10
|
|
|
11
11
|
// src/session-manager/journal.ts
|
|
12
12
|
import fs from "node:fs";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
writePrivateJsonFileSync
|
|
3
|
-
} from "./main-
|
|
3
|
+
} from "./main-20ahaz2q.mjs";
|
|
4
4
|
import {
|
|
5
5
|
dataRoot,
|
|
6
6
|
devExtensionUrl,
|
|
7
7
|
devExtensionFolder
|
|
8
|
-
} from "./main-
|
|
8
|
+
} from "./main-ma25hhqh.mjs";
|
|
9
9
|
|
|
10
10
|
// src/relay/browser-pairing.ts
|
|
11
11
|
import crypto from "node:crypto";
|