@opencode/browse 0.0.6-dev.17 → 0.0.6-dev.18
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-b4sbkefj.mjs → cli-z00ttket.mjs} +15 -16
- package/dist/cli.mjs +9 -9
- package/dist/{main-zwe0c783.mjs → main-0egy8naa.mjs} +7 -19
- package/dist/main-9y22cffn.mjs +130 -0
- package/dist/{main-kvmxefp1.mjs → main-d7rbre73.mjs} +3 -3
- package/dist/{main-e4stqtf2.mjs → main-fkhwazsm.mjs} +48 -79
- package/dist/{main-g5mke6rn.mjs → main-ha5bnd77.mjs} +2 -2
- package/dist/{main-3qpkwaa7.mjs → main-jjny7bmm.mjs} +6 -6
- package/dist/main-ppz7sv9s.mjs +4 -0
- package/dist/{main-4p2p9eey.mjs → main-w5sta7hq.mjs} +2 -2
- package/dist/{mcp-2smdsn8z.mjs → mcp-qh25n9s0.mjs} +6 -6
- package/dist/{relay-helpers-pjcbxs7p.mjs → relay-helpers-6a2vvzx9.mjs} +1 -1
- package/dist/{relay-ns525pms.mjs → relay-zs96tkfm.mjs} +42 -42
- package/dist/{runtime-update-0mddkfy5.mjs → runtime-update-8wte78jj.mjs} +6 -7
- package/dist/{setup-f2qjnvre.mjs → setup-cqjdfcy0.mjs} +7 -7
- package/dist/{update-cyy1grjj.mjs → update-st5c8grg.mjs} +2 -2
- package/dist/{version-wrebjhy7.mjs → version-6g6gtnra.mjs} +1 -1
- package/package.json +1 -1
- package/dist/main-4bht27ry.mjs +0 -72
- package/dist/main-y7c1atbf.mjs +0 -4
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
devExtension,
|
|
9
9
|
installCommand,
|
|
10
10
|
autoUpdateStatus
|
|
11
|
-
} from "./main-
|
|
11
|
+
} from "./main-ha5bnd77.mjs";
|
|
12
12
|
import {
|
|
13
13
|
defaultPort2,
|
|
14
14
|
isValidSessionId2,
|
|
@@ -27,11 +27,17 @@ import {
|
|
|
27
27
|
ensureExtensionConnected,
|
|
28
28
|
stoppedRelayStatus,
|
|
29
29
|
statusCollections
|
|
30
|
-
} from "./main-
|
|
30
|
+
} from "./main-jjny7bmm.mjs";
|
|
31
|
+
import"./main-9y22cffn.mjs";
|
|
31
32
|
import {
|
|
32
33
|
opencodeBrowserVersion2,
|
|
33
34
|
opencodeBrowserBuildId2
|
|
34
|
-
} from "./main-
|
|
35
|
+
} from "./main-ppz7sv9s.mjs";
|
|
36
|
+
import {
|
|
37
|
+
defaultJournalBaseDir,
|
|
38
|
+
readJournalEntries,
|
|
39
|
+
formatJournalEntry
|
|
40
|
+
} from "./main-d7rbre73.mjs";
|
|
35
41
|
import {
|
|
36
42
|
addSecret,
|
|
37
43
|
listSecrets,
|
|
@@ -43,18 +49,12 @@ import {
|
|
|
43
49
|
unpair,
|
|
44
50
|
settingKeys,
|
|
45
51
|
formatSettings
|
|
46
|
-
} from "./main-
|
|
47
|
-
import {
|
|
48
|
-
defaultJournalBaseDir,
|
|
49
|
-
readJournalEntries,
|
|
50
|
-
formatJournalEntry
|
|
51
|
-
} from "./main-kvmxefp1.mjs";
|
|
52
|
+
} from "./main-fkhwazsm.mjs";
|
|
52
53
|
import {
|
|
53
54
|
updateJson2,
|
|
54
55
|
formatUpdateNotice2,
|
|
55
56
|
updateNotice2
|
|
56
|
-
} from "./main-
|
|
57
|
-
import"./main-4bht27ry.mjs";
|
|
57
|
+
} from "./main-w5sta7hq.mjs";
|
|
58
58
|
|
|
59
59
|
// src/cli.ts
|
|
60
60
|
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
@@ -211,10 +211,9 @@ var createDoctorReport = Effect2.fn("Doctor.createReport")(function* (options) {
|
|
|
211
211
|
}
|
|
212
212
|
})));
|
|
213
213
|
const fileExists = (relativePath) => fs.exists(path.join(options.packageRoot, relativePath)).pipe(Effect2.orElseSucceed(() => false));
|
|
214
|
-
const [packageResult, distCliExists,
|
|
214
|
+
const [packageResult, distCliExists, currentResult] = yield* Effect2.all([
|
|
215
215
|
probe(readPackageInfo),
|
|
216
216
|
fileExists("dist/cli.mjs"),
|
|
217
|
-
fileExists("dist/cli.mjs"),
|
|
218
217
|
probe(store.read)
|
|
219
218
|
]);
|
|
220
219
|
const expectedExtensionVersion = packageResult.ok ? { ok: true, value: extensionManifestVersion(packageResult.value.version) } : packageResult;
|
|
@@ -248,7 +247,7 @@ var createDoctorReport = Effect2.fn("Doctor.createReport")(function* (options) {
|
|
|
248
247
|
return session.connected && session.id !== current;
|
|
249
248
|
});
|
|
250
249
|
const artifacts = [
|
|
251
|
-
{ path: "dist/cli.mjs", exists: distCliExists
|
|
250
|
+
{ path: "dist/cli.mjs", exists: distCliExists }
|
|
252
251
|
];
|
|
253
252
|
const checks = buildDoctorChecks({
|
|
254
253
|
packageResult,
|
|
@@ -811,7 +810,7 @@ function errorJsonEnvelope(error) {
|
|
|
811
810
|
return { ok: false, isError: true, text: message, value: null, valueUnavailable: true, error: errorValue, logs: [], warnings: [] };
|
|
812
811
|
}
|
|
813
812
|
var serve = Command.make("serve", {}, Effect3.fn("Cli.serve")(function* () {
|
|
814
|
-
const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect3.promise(() => Promise.all([import("./relay-
|
|
813
|
+
const [{ startRelay }, { parseAdditionalExtensionOrigins }] = yield* Effect3.promise(() => Promise.all([import("./relay-zs96tkfm.mjs"), import("./relay-helpers-6a2vvzx9.mjs")]));
|
|
815
814
|
const port = yield* portConfig;
|
|
816
815
|
const additionalExtensionOrigins = parseAdditionalExtensionOrigins(yield* extensionOriginsConfig);
|
|
817
816
|
yield* Effect3.scoped(Effect3.gen(function* () {
|
|
@@ -1681,7 +1680,7 @@ var settingsSet = Command.make("set", {
|
|
|
1681
1680
|
})).pipe(Command.withDescription("Change settings (validated strictly; the extension's options page updates live)"));
|
|
1682
1681
|
var settings = Command.make("settings").pipe(Command.withDescription("Read or change the user's settings (the extension's options page). Security switches are environment-only"), Command.withSubcommands([settingsGet, settingsSet]));
|
|
1683
1682
|
var mcp = Command.make("mcp", {}, Effect3.fn("Cli.mcp")(function* () {
|
|
1684
|
-
const { runMcpServer } = yield* Effect3.promise(() => import("./mcp-
|
|
1683
|
+
const { runMcpServer } = yield* Effect3.promise(() => import("./mcp-qh25n9s0.mjs"));
|
|
1685
1684
|
yield* runMcpServer;
|
|
1686
1685
|
})).pipe(Command.withDescription("Run the Browse MCP server over stdio"));
|
|
1687
1686
|
var opencodeBrowser = Command.make("opencode-browser").pipe(Command.withDescription("Control the user's existing browser through the Browse extension"), Command.withSubcommands([serve, relay, execute, session, tabs, settings, status, network, secrets, deadbolt, recording, flightRecorder, journal, doctor, skill, mcp]));
|
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.18";
|
|
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-6g6gtnra.mjs")).opencodeBrowserVersion;
|
|
11
11
|
process.stdout.write(`${opencodeBrowserVersion}
|
|
12
12
|
`);
|
|
13
|
-
} else if (invokedAs === "opencode-browser-mcp") {
|
|
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-qh25n9s0.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-8wte78jj.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-st5c8grg.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-cqjdfcy0.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-cqjdfcy0.mjs");
|
|
59
59
|
printSetupStatus();
|
|
60
60
|
}
|
|
61
|
-
const { runCli } = await import("./cli-
|
|
61
|
+
const { runCli } = await import("./cli-z00ttket.mjs");
|
|
62
62
|
runCli();
|
|
63
63
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./main-
|
|
2
|
+
writePrivateJsonFileSync
|
|
3
|
+
} from "./main-9y22cffn.mjs";
|
|
4
4
|
import {
|
|
5
5
|
dataRoot,
|
|
6
6
|
devExtensionUrl,
|
|
7
7
|
devExtensionFolder
|
|
8
|
-
} from "./main-
|
|
8
|
+
} from "./main-ha5bnd77.mjs";
|
|
9
9
|
|
|
10
10
|
// src/browser-pairing.ts
|
|
11
11
|
import crypto from "node:crypto";
|
|
@@ -45,7 +45,7 @@ function writePendingCodes(root, pending) {
|
|
|
45
45
|
fs.rmSync(pairingCodesPath(root), { force: true });
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
writePrivateJsonFileSync(pairingCodesPath(root), pending, { ensureParent: true });
|
|
49
49
|
}
|
|
50
50
|
function mintPairingCode(root = dataRoot(), options = {}) {
|
|
51
51
|
const now = options.now ?? Date.now();
|
|
@@ -71,7 +71,7 @@ function recordPairingFailure(root = dataRoot(), now = Date.now()) {
|
|
|
71
71
|
return exhausted && pending.codes.length > 0;
|
|
72
72
|
}
|
|
73
73
|
function writeExtensionPairing(extensionDirectory, code) {
|
|
74
|
-
|
|
74
|
+
writePrivateJsonFileSync(path.join(extensionDirectory, extensionPairingFileName), { code });
|
|
75
75
|
}
|
|
76
76
|
function readBrowserPairings(root = dataRoot()) {
|
|
77
77
|
try {
|
|
@@ -84,8 +84,7 @@ function readBrowserPairings(root = dataRoot()) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
function writeBrowserPairings(root, pairings) {
|
|
87
|
-
|
|
88
|
-
writePrivateJson(browserTokensPath(root), pairings);
|
|
87
|
+
writePrivateJsonFileSync(browserTokensPath(root), pairings, { ensureParent: true });
|
|
89
88
|
}
|
|
90
89
|
function browserToken(key, root = dataRoot()) {
|
|
91
90
|
return readBrowserPairings(root)[key]?.token;
|
|
@@ -155,12 +154,6 @@ function wrapToken(sessionKey, token) {
|
|
|
155
154
|
const mask = crypto.createHmac("sha256", sessionKey).update(`${context}|wrap`).digest();
|
|
156
155
|
return Buffer.from(Buffer.from(token, "base64url").map((byte, index) => byte ^ mask[index])).toString("base64url");
|
|
157
156
|
}
|
|
158
|
-
function writePrivateJson(file, value) {
|
|
159
|
-
const temporary = `${file}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
160
|
-
fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}
|
|
161
|
-
`, { mode: 384 });
|
|
162
|
-
fs.renameSync(temporary, file);
|
|
163
|
-
}
|
|
164
157
|
|
|
165
158
|
// src/dev-extension.ts
|
|
166
159
|
import { createHash } from "node:crypto";
|
|
@@ -299,12 +292,7 @@ function readRelayConfig(root = dataRoot()) {
|
|
|
299
292
|
}
|
|
300
293
|
}
|
|
301
294
|
function writeRelayConfig(config, root = dataRoot()) {
|
|
302
|
-
|
|
303
|
-
const file = relayConfigPath(root);
|
|
304
|
-
const temporary = `${file}.${process.pid}.tmp`;
|
|
305
|
-
fs2.writeFileSync(temporary, `${JSON.stringify(config, null, 2)}
|
|
306
|
-
`, { mode: 384 });
|
|
307
|
-
fs2.renameSync(temporary, file);
|
|
295
|
+
writePrivateJsonFileSync(relayConfigPath(root), config, { ensureParent: true });
|
|
308
296
|
}
|
|
309
297
|
var relayHostname = (root = dataRoot()) => readRelayConfig(root).hostname ?? "127.0.0.1";
|
|
310
298
|
function isLocalPeer(socket) {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dataRoot
|
|
3
|
+
} from "./main-ha5bnd77.mjs";
|
|
4
|
+
|
|
5
|
+
// src/relay-secrets.ts
|
|
6
|
+
import crypto2 from "node:crypto";
|
|
7
|
+
import fs2 from "node:fs";
|
|
8
|
+
import path2 from "node:path";
|
|
9
|
+
|
|
10
|
+
// src/fs-durability.ts
|
|
11
|
+
import { Predicate } from "effect";
|
|
12
|
+
import crypto from "node:crypto";
|
|
13
|
+
import fsSync from "node:fs";
|
|
14
|
+
import fs from "node:fs/promises";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
var unsupportedDirectorySyncCodes = new Set(["EPERM", "EINVAL", "ENOTSUP"]);
|
|
17
|
+
function isNodeError(error) {
|
|
18
|
+
return error instanceof Error && "code" in error;
|
|
19
|
+
}
|
|
20
|
+
function isUnsupportedDirectorySyncError(error) {
|
|
21
|
+
return isNodeError(error) && Predicate.isString(error.code) && unsupportedDirectorySyncCodes.has(error.code);
|
|
22
|
+
}
|
|
23
|
+
async function writeJsonFileAtomically(filePath, value, options = {}) {
|
|
24
|
+
const directory = path.dirname(filePath);
|
|
25
|
+
await fs.mkdir(directory, {
|
|
26
|
+
recursive: true,
|
|
27
|
+
...options.dirMode === undefined ? {} : { mode: options.dirMode }
|
|
28
|
+
});
|
|
29
|
+
if (options.dirMode !== undefined) {
|
|
30
|
+
await fs.chmod(directory, options.dirMode);
|
|
31
|
+
}
|
|
32
|
+
const temporaryPath = `${filePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
33
|
+
let renamed = false;
|
|
34
|
+
try {
|
|
35
|
+
await fs.writeFile(temporaryPath, `${JSON.stringify(value, null, 2)}
|
|
36
|
+
`, { mode: 384 });
|
|
37
|
+
await fs.rename(temporaryPath, filePath);
|
|
38
|
+
renamed = true;
|
|
39
|
+
await fs.chmod(filePath, 384);
|
|
40
|
+
} finally {
|
|
41
|
+
if (!renamed)
|
|
42
|
+
await fs.rm(temporaryPath, { force: true }).catch(() => {});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function ensurePrivateDirectorySync(directory) {
|
|
46
|
+
fsSync.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
47
|
+
if (process.platform !== "win32")
|
|
48
|
+
fsSync.chmodSync(directory, 448);
|
|
49
|
+
}
|
|
50
|
+
function writePrivateJsonFileSync(filePath, value, options = {}) {
|
|
51
|
+
if (options.ensureParent)
|
|
52
|
+
ensurePrivateDirectorySync(path.dirname(filePath));
|
|
53
|
+
const temporaryPath = `${filePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
54
|
+
let renamed = false;
|
|
55
|
+
try {
|
|
56
|
+
fsSync.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}
|
|
57
|
+
`, { mode: 384 });
|
|
58
|
+
fsSync.renameSync(temporaryPath, filePath);
|
|
59
|
+
renamed = true;
|
|
60
|
+
if (process.platform !== "win32")
|
|
61
|
+
fsSync.chmodSync(filePath, 384);
|
|
62
|
+
} finally {
|
|
63
|
+
if (!renamed)
|
|
64
|
+
fsSync.rmSync(temporaryPath, { force: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/relay-secrets.ts
|
|
69
|
+
var relayTokenQueryParam = "opencodeBrowserToken";
|
|
70
|
+
var tokenPattern = /^[A-Za-z0-9_-]{43}$/;
|
|
71
|
+
function relayTokenPath(root = dataRoot()) {
|
|
72
|
+
return path2.join(root, "relay-token");
|
|
73
|
+
}
|
|
74
|
+
function relayToken(root = dataRoot()) {
|
|
75
|
+
return readOrCreateSecret(relayTokenPath(root), () => crypto2.randomBytes(32).toString("base64url"), (value) => tokenPattern.test(value));
|
|
76
|
+
}
|
|
77
|
+
function relayAuthorization(root = dataRoot()) {
|
|
78
|
+
return `Bearer ${relayToken(root)}`;
|
|
79
|
+
}
|
|
80
|
+
function secretsEqual(expected, actual) {
|
|
81
|
+
if (actual === undefined)
|
|
82
|
+
return false;
|
|
83
|
+
const a = crypto2.createHash("sha256").update(expected).digest();
|
|
84
|
+
const b = crypto2.createHash("sha256").update(actual).digest();
|
|
85
|
+
return crypto2.timingSafeEqual(a, b) && expected.length === actual.length;
|
|
86
|
+
}
|
|
87
|
+
function readOrCreateSecret(file, generate, valid) {
|
|
88
|
+
const existing = readSecret(file);
|
|
89
|
+
if (existing !== undefined && valid(existing))
|
|
90
|
+
return existing;
|
|
91
|
+
ensurePrivateDirectory(path2.dirname(file));
|
|
92
|
+
const temporary = `${file}.${process.pid}.${crypto2.randomUUID()}.tmp`;
|
|
93
|
+
fs2.writeFileSync(temporary, `${generate()}
|
|
94
|
+
`, { mode: 384 });
|
|
95
|
+
try {
|
|
96
|
+
if (existing === undefined) {
|
|
97
|
+
try {
|
|
98
|
+
fs2.linkSync(temporary, file);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error.code !== "EEXIST")
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
fs2.renameSync(temporary, file);
|
|
105
|
+
}
|
|
106
|
+
} finally {
|
|
107
|
+
fs2.rmSync(temporary, { force: true });
|
|
108
|
+
}
|
|
109
|
+
const created = readSecret(file);
|
|
110
|
+
if (created === undefined || !valid(created))
|
|
111
|
+
throw new Error(`Could not create ${file}`);
|
|
112
|
+
return created;
|
|
113
|
+
}
|
|
114
|
+
function readSecret(file) {
|
|
115
|
+
try {
|
|
116
|
+
const stat = fs2.statSync(file);
|
|
117
|
+
if (process.platform !== "win32" && (stat.mode & 63) !== 0)
|
|
118
|
+
fs2.chmodSync(file, 384);
|
|
119
|
+
return fs2.readFileSync(file, "utf8").trim();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (error.code === "ENOENT")
|
|
122
|
+
return;
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function ensurePrivateDirectory(directory = dataRoot()) {
|
|
127
|
+
ensurePrivateDirectorySync(directory);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { isNodeError, isUnsupportedDirectorySyncError, writeJsonFileAtomically, ensurePrivateDirectorySync, writePrivateJsonFileSync, relayTokenQueryParam, relayToken, relayAuthorization, secretsEqual, ensurePrivateDirectory };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isNodeError
|
|
3
|
-
} from "./main-
|
|
3
|
+
} from "./main-9y22cffn.mjs";
|
|
4
4
|
import {
|
|
5
5
|
dataRoot
|
|
6
|
-
} from "./main-
|
|
6
|
+
} from "./main-ha5bnd77.mjs";
|
|
7
7
|
import {
|
|
8
8
|
isValidSessionId2
|
|
9
|
-
} from "./main-
|
|
9
|
+
} from "./main-jjny7bmm.mjs";
|
|
10
10
|
|
|
11
11
|
// src/session-journal.ts
|
|
12
12
|
import fs from "node:fs";
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isNodeError,
|
|
3
|
+
writeJsonFileAtomically
|
|
4
|
+
} from "./main-9y22cffn.mjs";
|
|
1
5
|
import {
|
|
2
6
|
dataRoot,
|
|
3
7
|
cliCommand
|
|
4
|
-
} from "./main-
|
|
8
|
+
} from "./main-ha5bnd77.mjs";
|
|
5
9
|
|
|
6
10
|
// src/site-secrets.ts
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
11
|
+
import crypto from "node:crypto";
|
|
12
|
+
import fs2 from "node:fs/promises";
|
|
13
|
+
import path2 from "node:path";
|
|
10
14
|
import { Effect as Effect2, Schema as Schema2 } from "effect";
|
|
11
15
|
|
|
12
16
|
// src/auth-profile.ts
|
|
13
17
|
import { Effect, Schema, Semaphore } from "effect";
|
|
14
18
|
import { spawn } from "node:child_process";
|
|
15
|
-
import
|
|
16
|
-
import
|
|
19
|
+
import fs from "node:fs/promises";
|
|
20
|
+
import path from "node:path";
|
|
17
21
|
|
|
18
22
|
// src/child-process.ts
|
|
19
23
|
async function terminateChildProcess(options) {
|
|
@@ -45,43 +49,8 @@ function signalChildProcess(child, signal) {
|
|
|
45
49
|
child.kill(signal);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
// src/fs-durability.ts
|
|
49
|
-
import { Predicate } from "effect";
|
|
50
|
-
import crypto from "node:crypto";
|
|
51
|
-
import fs from "node:fs/promises";
|
|
52
|
-
import path from "node:path";
|
|
53
|
-
var unsupportedDirectorySyncCodes = new Set(["EPERM", "EINVAL", "ENOTSUP"]);
|
|
54
|
-
function isNodeError(error) {
|
|
55
|
-
return error instanceof Error && "code" in error;
|
|
56
|
-
}
|
|
57
|
-
function isUnsupportedDirectorySyncError(error) {
|
|
58
|
-
return isNodeError(error) && Predicate.isString(error.code) && unsupportedDirectorySyncCodes.has(error.code);
|
|
59
|
-
}
|
|
60
|
-
async function writeJsonFileAtomically(filePath, value, options = {}) {
|
|
61
|
-
const directory = path.dirname(filePath);
|
|
62
|
-
await fs.mkdir(directory, {
|
|
63
|
-
recursive: true,
|
|
64
|
-
...options.dirMode === undefined ? {} : { mode: options.dirMode }
|
|
65
|
-
});
|
|
66
|
-
if (options.dirMode !== undefined) {
|
|
67
|
-
await fs.chmod(directory, options.dirMode);
|
|
68
|
-
}
|
|
69
|
-
const temporaryPath = `${filePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
70
|
-
let renamed = false;
|
|
71
|
-
try {
|
|
72
|
-
await fs.writeFile(temporaryPath, `${JSON.stringify(value, null, 2)}
|
|
73
|
-
`, { mode: 384 });
|
|
74
|
-
await fs.rename(temporaryPath, filePath);
|
|
75
|
-
renamed = true;
|
|
76
|
-
await fs.chmod(filePath, 384);
|
|
77
|
-
} finally {
|
|
78
|
-
if (!renamed)
|
|
79
|
-
await fs.rm(temporaryPath, { force: true }).catch(() => {});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
52
|
// src/network-redaction.ts
|
|
84
|
-
import { Predicate
|
|
53
|
+
import { Predicate } from "effect";
|
|
85
54
|
var secretNamePattern = /auth(?:orization)?|cookie|credential|csrf|xsrf|token|secret|session|password|passwd|pwd|passcode|otp|(?:^|[-_.])code(?:$|[-_.])|(?:api|access|refresh)[-_.]?key|signature|(?:^|[-_.])sig(?:$|[-_.])/i;
|
|
86
55
|
var oneTimeFieldPattern = /pass(?:word|wd|code|phrase)|(?:^|[-_.])pwd(?:$|[-_.])|otp|totp|(?:^|[-_.])(?:mfa_?|2fa_?|verification_?|auth_?)?code(?:$|[-_.])|(?:^|[-_.])pin(?:$|[-_.])/i;
|
|
87
56
|
var referencePattern = String.raw`BC_(?:SECRET|REDACTED)_\d+`;
|
|
@@ -188,7 +157,7 @@ class SecretCollector {
|
|
|
188
157
|
return redactKnownValue(value, this.redactionSlots());
|
|
189
158
|
}
|
|
190
159
|
redactExactValue(value, minimumLength) {
|
|
191
|
-
if (!
|
|
160
|
+
if (!Predicate.isString(value) && !Predicate.isNumber(value) && !Predicate.isBoolean(value))
|
|
192
161
|
return value;
|
|
193
162
|
const serialized = String(value);
|
|
194
163
|
if (serialized.length < minimumLength)
|
|
@@ -279,7 +248,7 @@ class SecretCollector {
|
|
|
279
248
|
if (Array.isArray(value)) {
|
|
280
249
|
return value.map((item, index) => this.protectJson(item, location, [...path, String(index)], inSecret));
|
|
281
250
|
}
|
|
282
|
-
if (
|
|
251
|
+
if (Predicate.isObject(value)) {
|
|
283
252
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
284
253
|
key,
|
|
285
254
|
this.protectJson(item, location, [...path, key], inSecret || secretNamePattern.test(key))
|
|
@@ -473,15 +442,15 @@ function redactKnownValues(text, slots) {
|
|
|
473
442
|
return [...slots].sort((left, right) => right.value.length - left.value.length).reduce((output, slot) => replaceOutsideReferences(output, slot.value, `\${${slot.ref}}`), text);
|
|
474
443
|
}
|
|
475
444
|
function redactKnownValue(value, slots) {
|
|
476
|
-
if (
|
|
445
|
+
if (Predicate.isString(value))
|
|
477
446
|
return redactKnownValues(value, slots);
|
|
478
|
-
if (
|
|
447
|
+
if (Predicate.isNumber(value) || Predicate.isBoolean(value)) {
|
|
479
448
|
const slot = slots.find((candidate) => candidate.value === String(value));
|
|
480
449
|
return slot ? `\${${slot.ref}}` : value;
|
|
481
450
|
}
|
|
482
451
|
if (Array.isArray(value))
|
|
483
452
|
return value.map((item) => redactKnownValue(item, slots));
|
|
484
|
-
if (!
|
|
453
|
+
if (!Predicate.isObject(value))
|
|
485
454
|
return value;
|
|
486
455
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
487
456
|
key,
|
|
@@ -491,7 +460,7 @@ function redactKnownValue(value, slots) {
|
|
|
491
460
|
function redactSecretValue(value) {
|
|
492
461
|
if (Array.isArray(value))
|
|
493
462
|
return value.map(redactSecretValue);
|
|
494
|
-
if (
|
|
463
|
+
if (Predicate.isObject(value)) {
|
|
495
464
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, redactSecretValue(item)]));
|
|
496
465
|
}
|
|
497
466
|
return value === null || value === "" ? value : "[REDACTED]";
|
|
@@ -516,7 +485,7 @@ function jwtExpiration(value) {
|
|
|
516
485
|
return;
|
|
517
486
|
try {
|
|
518
487
|
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
519
|
-
return
|
|
488
|
+
return Predicate.isNumber(payload.exp) ? new Date(payload.exp * 1000).toISOString() : undefined;
|
|
520
489
|
} catch {
|
|
521
490
|
return;
|
|
522
491
|
}
|
|
@@ -550,7 +519,7 @@ class AuthProfileError extends Schema.TaggedError()("AuthProfile.Error", {
|
|
|
550
519
|
cause: Schema.optionalKey(Schema.Defect())
|
|
551
520
|
}) {
|
|
552
521
|
}
|
|
553
|
-
var defaultBaseDir = () =>
|
|
522
|
+
var defaultBaseDir = () => path.join(dataRoot(), "secrets");
|
|
554
523
|
var writeLock = Semaphore.makeUnsafe(1);
|
|
555
524
|
var profileLockTimeoutMs = 30000;
|
|
556
525
|
var staleProfileLockMs = 60000;
|
|
@@ -559,7 +528,7 @@ var maximumTimeoutMs = 2147483647;
|
|
|
559
528
|
var read = Effect.fn("AuthProfile.read")(function* (name, options = {}) {
|
|
560
529
|
const filePath = yield* profilePath(options.baseDir ?? defaultBaseDir(), name);
|
|
561
530
|
const text = yield* Effect.tryPromise({
|
|
562
|
-
try: () =>
|
|
531
|
+
try: () => fs.readFile(filePath, "utf8"),
|
|
563
532
|
catch: (cause) => isNodeError(cause) && cause.code === "ENOENT" ? new AuthProfileError({ message: `Auth profile not found: ${name}`, operation: "read", reason: "not-found", cause }) : new AuthProfileError({ message: `Could not read auth profile: ${name}`, operation: "read", reason: "read-failed", cause })
|
|
564
533
|
});
|
|
565
534
|
return yield* Schema.decodeUnknownEffect(StoredAuthProfile)(yield* Effect.try({
|
|
@@ -577,12 +546,12 @@ function withLock(name, options, effect) {
|
|
|
577
546
|
const lockPath = `${filePath}.lock`;
|
|
578
547
|
yield* Effect.tryPromise({
|
|
579
548
|
try: async () => {
|
|
580
|
-
await
|
|
581
|
-
await
|
|
549
|
+
await fs.mkdir(baseDir, { recursive: true, mode: 448 });
|
|
550
|
+
await fs.chmod(baseDir, 448);
|
|
582
551
|
const deadline = Date.now() + profileLockTimeoutMs;
|
|
583
552
|
while (true) {
|
|
584
553
|
try {
|
|
585
|
-
const handle = await
|
|
554
|
+
const handle = await fs.open(lockPath, "wx", 384);
|
|
586
555
|
let written = false;
|
|
587
556
|
try {
|
|
588
557
|
await handle.writeFile(`${process.pid}
|
|
@@ -591,17 +560,17 @@ function withLock(name, options, effect) {
|
|
|
591
560
|
} finally {
|
|
592
561
|
await handle.close();
|
|
593
562
|
if (!written)
|
|
594
|
-
await
|
|
563
|
+
await fs.unlink(lockPath).catch(() => {});
|
|
595
564
|
}
|
|
596
565
|
return;
|
|
597
566
|
} catch (cause) {
|
|
598
567
|
if (!isNodeError(cause) || cause.code !== "EEXIST")
|
|
599
568
|
throw cause;
|
|
600
|
-
const stat = await
|
|
569
|
+
const stat = await fs.stat(lockPath).catch(() => {
|
|
601
570
|
return;
|
|
602
571
|
});
|
|
603
572
|
if (stat && Date.now() - stat.mtimeMs > staleProfileLockMs) {
|
|
604
|
-
await
|
|
573
|
+
await fs.unlink(lockPath).catch(() => {});
|
|
605
574
|
continue;
|
|
606
575
|
}
|
|
607
576
|
if (Date.now() >= deadline)
|
|
@@ -615,7 +584,7 @@ function withLock(name, options, effect) {
|
|
|
615
584
|
return lockPath;
|
|
616
585
|
});
|
|
617
586
|
return Effect.acquireUseRelease(acquire, () => effect, (lockPath) => Effect.tryPromise({
|
|
618
|
-
try: () =>
|
|
587
|
+
try: () => fs.unlink(lockPath).catch(() => {}).then(() => {}),
|
|
619
588
|
catch: (cause) => new AuthProfileError({ message: `Could not release auth profile lock: ${name}`, operation: "lock", reason: "write-failed", cause })
|
|
620
589
|
}));
|
|
621
590
|
}
|
|
@@ -701,7 +670,7 @@ function summary(profile) {
|
|
|
701
670
|
};
|
|
702
671
|
}
|
|
703
672
|
function profilePath(baseDir, name) {
|
|
704
|
-
return /^[a-z0-9][a-z0-9._-]{0,63}$/i.test(name) ? Effect.succeed(
|
|
673
|
+
return /^[a-z0-9][a-z0-9._-]{0,63}$/i.test(name) ? Effect.succeed(path.join(baseDir, `${name}.json`)) : Effect.fail(new AuthProfileError({ message: `Invalid auth profile name: ${name}`, operation: "path", reason: "invalid-name" }));
|
|
705
674
|
}
|
|
706
675
|
function sameSlots(left, right) {
|
|
707
676
|
return JSON.stringify(left) === JSON.stringify(right);
|
|
@@ -1018,10 +987,10 @@ class SiteSecretError extends Schema2.TaggedError()("SiteSecret.Error", {
|
|
|
1018
987
|
cause: Schema2.optionalKey(Schema2.Defect())
|
|
1019
988
|
}) {
|
|
1020
989
|
}
|
|
1021
|
-
var defaultSiteSecretsDir = () =>
|
|
990
|
+
var defaultSiteSecretsDir = () => path2.join(dataRoot(), "site-secrets");
|
|
1022
991
|
var namePattern = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
|
|
1023
992
|
function secretPath(baseDir, name) {
|
|
1024
|
-
return namePattern.test(name) ? Effect2.succeed(
|
|
993
|
+
return namePattern.test(name) ? Effect2.succeed(path2.join(baseDir, `${name}.json`)) : Effect2.fail(new SiteSecretError({ message: `Invalid secret name: ${name} (letters, digits, ".", "_" and "-", up to 64)`, reason: "invalid-name" }));
|
|
1025
994
|
}
|
|
1026
995
|
function summary2(secret) {
|
|
1027
996
|
return { name: secret.name, kind: secret.kind, allowedOrigins: [...secret.allowedOrigins], createdAt: secret.createdAt, updatedAt: secret.updatedAt };
|
|
@@ -1029,7 +998,7 @@ function summary2(secret) {
|
|
|
1029
998
|
var readSecret = Effect2.fn("SiteSecrets.read")(function* (name, options = {}) {
|
|
1030
999
|
const filePath = yield* secretPath(options.baseDir ?? defaultSiteSecretsDir(), name);
|
|
1031
1000
|
const text = yield* Effect2.tryPromise({
|
|
1032
|
-
try: () =>
|
|
1001
|
+
try: () => fs2.readFile(filePath, "utf8"),
|
|
1033
1002
|
catch: (cause) => isNodeError(cause) && cause.code === "ENOENT" ? new SiteSecretError({ message: `Secret not found: ${name}. Ask the user to add it with \`opencode-browser secrets add ${name} --origin <origin>\`.`, reason: "not-found" }) : new SiteSecretError({ message: `Could not read secret ${name}`, reason: "read-failed", cause })
|
|
1034
1003
|
});
|
|
1035
1004
|
return yield* Effect2.try({
|
|
@@ -1071,7 +1040,7 @@ var addSecret = Effect2.fn("SiteSecrets.add")(function* (options) {
|
|
|
1071
1040
|
var listSecrets = Effect2.fn("SiteSecrets.list")(function* (options = {}) {
|
|
1072
1041
|
const baseDir = options.baseDir ?? defaultSiteSecretsDir();
|
|
1073
1042
|
const names = yield* Effect2.tryPromise({
|
|
1074
|
-
try: () =>
|
|
1043
|
+
try: () => fs2.readdir(baseDir).catch((cause) => isNodeError(cause) && cause.code === "ENOENT" ? [] : Promise.reject(cause)),
|
|
1075
1044
|
catch: (cause) => new SiteSecretError({ message: "Could not list secrets", reason: "read-failed", cause })
|
|
1076
1045
|
});
|
|
1077
1046
|
const secrets = [];
|
|
@@ -1086,7 +1055,7 @@ var removeSecret = Effect2.fn("SiteSecrets.remove")(function* (name, options = {
|
|
|
1086
1055
|
const baseDir = options.baseDir ?? defaultSiteSecretsDir();
|
|
1087
1056
|
const filePath = yield* secretPath(baseDir, name);
|
|
1088
1057
|
return yield* withLock(name, { baseDir }, Effect2.tryPromise({
|
|
1089
|
-
try: () =>
|
|
1058
|
+
try: () => fs2.rm(filePath).then(() => true, (cause) => isNodeError(cause) && cause.code === "ENOENT" ? false : Promise.reject(cause)),
|
|
1090
1059
|
catch: (cause) => new SiteSecretError({ message: `Could not remove secret ${name}`, reason: "write-failed", cause })
|
|
1091
1060
|
})).pipe(Effect2.mapError((error) => error instanceof SiteSecretError ? error : new SiteSecretError({ message: error.message, reason: "write-failed", cause: error })));
|
|
1092
1061
|
});
|
|
@@ -1128,7 +1097,7 @@ function totpCode(seed, now = Date.now()) {
|
|
|
1128
1097
|
const { key, digits, period, algorithm } = totpParameters(seed);
|
|
1129
1098
|
const counter = Buffer.alloc(8);
|
|
1130
1099
|
counter.writeBigUInt64BE(BigInt(Math.floor(now / 1000 / period)));
|
|
1131
|
-
const hmac =
|
|
1100
|
+
const hmac = crypto.createHmac(algorithm, key).update(counter).digest();
|
|
1132
1101
|
const offset = hmac[hmac.length - 1] & 15;
|
|
1133
1102
|
const binary = (hmac.readUInt32BE(offset) & 2147483647) % 10 ** digits;
|
|
1134
1103
|
return String(binary).padStart(digits, "0");
|
|
@@ -1139,11 +1108,11 @@ function secretText(secret) {
|
|
|
1139
1108
|
|
|
1140
1109
|
// src/deadbolt.ts
|
|
1141
1110
|
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
1142
|
-
import
|
|
1143
|
-
import
|
|
1111
|
+
import crypto2 from "node:crypto";
|
|
1112
|
+
import fs3 from "node:fs";
|
|
1144
1113
|
import net2 from "node:net";
|
|
1145
1114
|
import os from "node:os";
|
|
1146
|
-
import
|
|
1115
|
+
import path3 from "node:path";
|
|
1147
1116
|
class DeadboltError extends Error {
|
|
1148
1117
|
name = "DeadboltError";
|
|
1149
1118
|
code;
|
|
@@ -1156,16 +1125,16 @@ class DeadboltError extends Error {
|
|
|
1156
1125
|
}
|
|
1157
1126
|
var clientFileName = "deadbolt-client.json";
|
|
1158
1127
|
function clientFilePath(root = dataRoot()) {
|
|
1159
|
-
return
|
|
1128
|
+
return path3.join(root, clientFileName);
|
|
1160
1129
|
}
|
|
1161
1130
|
function readClientFile(root = dataRoot()) {
|
|
1162
1131
|
let text;
|
|
1163
1132
|
try {
|
|
1164
1133
|
const file = clientFilePath(root);
|
|
1165
|
-
const stat =
|
|
1134
|
+
const stat = fs3.statSync(file);
|
|
1166
1135
|
if (process.platform !== "win32" && (stat.mode & 63) !== 0)
|
|
1167
|
-
|
|
1168
|
-
text =
|
|
1136
|
+
fs3.chmodSync(file, 384);
|
|
1137
|
+
text = fs3.readFileSync(file, "utf8");
|
|
1169
1138
|
} catch {
|
|
1170
1139
|
return;
|
|
1171
1140
|
}
|
|
@@ -1193,9 +1162,9 @@ async function saveClient(client, root = dataRoot()) {
|
|
|
1193
1162
|
}
|
|
1194
1163
|
function removeClient(root = dataRoot()) {
|
|
1195
1164
|
const file = clientFilePath(root);
|
|
1196
|
-
if (!
|
|
1165
|
+
if (!fs3.existsSync(file))
|
|
1197
1166
|
return false;
|
|
1198
|
-
|
|
1167
|
+
fs3.rmSync(file, { force: true });
|
|
1199
1168
|
return true;
|
|
1200
1169
|
}
|
|
1201
1170
|
function computedSocketPath(env = process.env) {
|
|
@@ -1204,13 +1173,13 @@ function computedSocketPath(env = process.env) {
|
|
|
1204
1173
|
const suffix = deadboltHome ? `-${blake3Hex(Buffer.from(deadboltHome, "utf8")).slice(0, 8)}` : "";
|
|
1205
1174
|
const uid = typeof process.getuid === "function" ? process.getuid() : 0;
|
|
1206
1175
|
const runtime = nonEmpty("XDG_RUNTIME_DIR") ?? userRuntimeDir(uid);
|
|
1207
|
-
const directory = runtime ?
|
|
1208
|
-
return
|
|
1176
|
+
const directory = runtime ? path3.join(runtime, `deadbolt${suffix}`) : path3.join(nonEmpty("TMPDIR") ?? os.tmpdir(), `deadbolt${suffix}-${uid}`);
|
|
1177
|
+
return path3.join(directory, "agent.sock");
|
|
1209
1178
|
}
|
|
1210
1179
|
function userRuntimeDir(uid) {
|
|
1211
1180
|
const directory = `/run/user/${uid}`;
|
|
1212
1181
|
try {
|
|
1213
|
-
const stat =
|
|
1182
|
+
const stat = fs3.statSync(directory);
|
|
1214
1183
|
return stat.isDirectory() && stat.uid === uid ? directory : undefined;
|
|
1215
1184
|
} catch {
|
|
1216
1185
|
return;
|
|
@@ -1519,7 +1488,7 @@ function isBase64Url(value, maxLength = 8192) {
|
|
|
1519
1488
|
return typeof value === "string" && value.length <= maxLength && /^[A-Za-z0-9_-]*$/.test(value);
|
|
1520
1489
|
}
|
|
1521
1490
|
function randomName(prefix) {
|
|
1522
|
-
return `${prefix}${
|
|
1491
|
+
return `${prefix}${crypto2.randomBytes(12).toString("hex")}`;
|
|
1523
1492
|
}
|
|
1524
1493
|
var blake3Iv = [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225];
|
|
1525
1494
|
var blake3Permutation = [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8];
|
|
@@ -1695,4 +1664,4 @@ function formatSettings(settings) {
|
|
|
1695
1664
|
});
|
|
1696
1665
|
}
|
|
1697
1666
|
|
|
1698
|
-
export { terminateChildProcess,
|
|
1667
|
+
export { terminateChildProcess, SecretCollector, looksLikeTokenSegment, AuthProfileError, read, readOptional, withLock, write, status, run, OriginPatternError, parseOriginPatterns, normalizeOriginPatterns, isPrivateAddress, explicitlyAllowsHost, checkUrl, checkNavigationUrl, readSecret, addSecret, listSecrets, removeSecret, secretText, DeadboltError, readClient, socketPath, connect, parseDeadboltName, originOnSite, pickLogin, originsFromPatterns, listLogins, pickPasskey, pair, unpair, isBase64Url, randomName, settingKeys, settingSpecs, securityVariables, SettingsInputError, parseSettingChanges, settingsFromExtension, settingsToExtension, describeSettings, describeChanges, formatSettings };
|
|
@@ -147,7 +147,7 @@ function storeConfig(env = process.env, baked = { id: "mfnicocicmmlkpjnaffgihfjh
|
|
|
147
147
|
return id ? { id } : {};
|
|
148
148
|
}
|
|
149
149
|
var RELEASE_SERVICE = "https://anoma.ly/release";
|
|
150
|
-
function devExtension(baked = { file: "browse-extension-0.0.6-dev.
|
|
150
|
+
function devExtension(baked = { file: "browse-extension-0.0.6-dev.18.zip", sha256: "2f8f69b9022f9835f564f96ccc5fd07c48ad78e95488eeb2a83f253d8fafbb49", size: 38413 }) {
|
|
151
151
|
return baked && /^[0-9a-f]{64}$/.test(baked.sha256) && /^[\w.-]+\.zip$/.test(baked.file) ? baked : undefined;
|
|
152
152
|
}
|
|
153
153
|
var devExtensionUrl = (extension, env = process.env) => `${(env.OPENCODE_BROWSER_RELEASE_SERVICE || RELEASE_SERVICE).replace(/\/+$/, "")}/browse/files/${extension.sha256}/${extension.file}`;
|
|
@@ -728,4 +728,4 @@ function spawnRuntimeChild(layout, entry, args, onExit, env = process.env) {
|
|
|
728
728
|
}
|
|
729
729
|
}
|
|
730
730
|
|
|
731
|
-
export { extensionProtocolVersion, minExtensionProtocolVersion, unpackedExtensionId, unpackedReloadAdvice, checkoutReloadPrefix, extensionReconnectAlarmPeriodMs, extensionProtocolCompatibility, extensionProtocolSkew, extensionProtocolAdvice, makePageStatus, parseJsonObject, isCdpRequest, isExtensionResponse, isExtensionEvent, isJsonObject, dataRoot, oldStoreMarker, fromCheckout, checkoutRoot, cliCommand, storeConfig, devExtension, devExtensionUrl, devExtensionFolder, storeUrl, installCommand, autoUpdateModes, runtimeLayout, versionEntry, channelOf, UPDATE_VERSION, compareVersions, readCurrent, writeCurrent,
|
|
731
|
+
export { extensionProtocolVersion, minExtensionProtocolVersion, unpackedExtensionId, unpackedReloadAdvice, checkoutReloadPrefix, extensionReconnectAlarmPeriodMs, extensionProtocolCompatibility, extensionProtocolSkew, extensionProtocolAdvice, makePageStatus, parseJsonObject, isCdpRequest, isExtensionResponse, isExtensionEvent, isJsonObject, dataRoot, oldStoreMarker, fromCheckout, checkoutRoot, cliCommand, storeConfig, devExtension, devExtensionUrl, devExtensionFolder, storeUrl, installCommand, autoUpdateModes, runtimeLayout, versionEntry, channelOf, UPDATE_VERSION, compareVersions, readCurrent, writeCurrent, updateState, npmRuntime, autoUpdateOverride, storedMode, effectiveMode, setStoredMode, autoUpdateStatus, describeAutoUpdate, registryUrl, fetchPublished, installVersion, pruneVersions, switchVersion, createAutoUpdater };
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
cliCommand,
|
|
7
7
|
installCommand,
|
|
8
8
|
npmRuntime
|
|
9
|
-
} from "./main-
|
|
10
|
-
import {
|
|
11
|
-
opencodeBrowserBuildId2
|
|
12
|
-
} from "./main-y7c1atbf.mjs";
|
|
9
|
+
} from "./main-ha5bnd77.mjs";
|
|
13
10
|
import {
|
|
14
11
|
relayAuthorization
|
|
15
|
-
} from "./main-
|
|
12
|
+
} from "./main-9y22cffn.mjs";
|
|
13
|
+
import {
|
|
14
|
+
opencodeBrowserBuildId2
|
|
15
|
+
} from "./main-ppz7sv9s.mjs";
|
|
16
16
|
|
|
17
17
|
// src/relay-helpers.ts
|
|
18
18
|
import crypto from "node:crypto";
|
|
@@ -1408,7 +1408,7 @@ function managedRelayLaunch(entrypoint = loadedCliEntrypoint, executable = proce
|
|
|
1408
1408
|
}
|
|
1409
1409
|
function managedRelayEntrypoint(entrypoint) {
|
|
1410
1410
|
const name = path.basename(entrypoint);
|
|
1411
|
-
if (name === "
|
|
1411
|
+
if (name === "index.ts" || name === "opencode-browser-client.ts" || name === "cli.ts")
|
|
1412
1412
|
return path.join(path.dirname(entrypoint), "main.ts");
|
|
1413
1413
|
return entrypoint;
|
|
1414
1414
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
compareVersions,
|
|
7
7
|
npmRuntime,
|
|
8
8
|
autoUpdateStatus
|
|
9
|
-
} from "./main-
|
|
9
|
+
} from "./main-ha5bnd77.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-8wte78jj.mjs");
|
|
316
316
|
if (await runNpmUpdate(args))
|
|
317
317
|
return;
|
|
318
318
|
if (args.includes("--check")) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoUpdateStatus
|
|
3
|
-
} from "./main-
|
|
3
|
+
} from "./main-ha5bnd77.mjs";
|
|
4
4
|
import {
|
|
5
5
|
parseTargetSelection2,
|
|
6
6
|
getObject2,
|
|
@@ -10,22 +10,22 @@ import {
|
|
|
10
10
|
relayBuildProblem,
|
|
11
11
|
ensureRelay,
|
|
12
12
|
ensureExtensionConnected
|
|
13
|
-
} from "./main-
|
|
13
|
+
} from "./main-jjny7bmm.mjs";
|
|
14
|
+
import"./main-9y22cffn.mjs";
|
|
14
15
|
import {
|
|
15
16
|
opencodeBrowserVersion2
|
|
16
|
-
} from "./main-
|
|
17
|
+
} from "./main-ppz7sv9s.mjs";
|
|
17
18
|
import {
|
|
18
19
|
listSecrets,
|
|
19
20
|
readClient,
|
|
20
21
|
settingKeys,
|
|
21
22
|
settingSpecs,
|
|
22
23
|
securityVariables
|
|
23
|
-
} from "./main-
|
|
24
|
+
} from "./main-fkhwazsm.mjs";
|
|
24
25
|
import {
|
|
25
26
|
updateJson2,
|
|
26
27
|
createUpdateWatcher2
|
|
27
|
-
} from "./main-
|
|
28
|
-
import"./main-4bht27ry.mjs";
|
|
28
|
+
} from "./main-w5sta7hq.mjs";
|
|
29
29
|
|
|
30
30
|
// src/mcp.ts
|
|
31
31
|
import { NodeStdio } from "@effect/platform-node";
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
setStoredMode,
|
|
26
26
|
autoUpdateStatus,
|
|
27
27
|
createAutoUpdater
|
|
28
|
-
} from "./main-
|
|
28
|
+
} from "./main-ha5bnd77.mjs";
|
|
29
29
|
import {
|
|
30
30
|
ExecuteRequest,
|
|
31
31
|
SessionAdoptRequest,
|
|
@@ -75,7 +75,18 @@ import {
|
|
|
75
75
|
isRestrictedTarget2,
|
|
76
76
|
isRestrictedUrl2,
|
|
77
77
|
dataUrlDocument2
|
|
78
|
-
} from "./main-
|
|
78
|
+
} from "./main-jjny7bmm.mjs";
|
|
79
|
+
import {
|
|
80
|
+
isNodeError,
|
|
81
|
+
isUnsupportedDirectorySyncError,
|
|
82
|
+
writeJsonFileAtomically,
|
|
83
|
+
ensurePrivateDirectorySync,
|
|
84
|
+
writePrivateJsonFileSync,
|
|
85
|
+
relayTokenQueryParam,
|
|
86
|
+
relayToken,
|
|
87
|
+
secretsEqual,
|
|
88
|
+
ensurePrivateDirectory
|
|
89
|
+
} from "./main-9y22cffn.mjs";
|
|
79
90
|
import {
|
|
80
91
|
context,
|
|
81
92
|
pendingPairingCodeKeys,
|
|
@@ -97,12 +108,9 @@ import {
|
|
|
97
108
|
syncDevExtension,
|
|
98
109
|
relayHostname,
|
|
99
110
|
isLocalPeer
|
|
100
|
-
} from "./main-
|
|
111
|
+
} from "./main-0egy8naa.mjs";
|
|
101
112
|
import {
|
|
102
113
|
terminateChildProcess,
|
|
103
|
-
isNodeError,
|
|
104
|
-
isUnsupportedDirectorySyncError,
|
|
105
|
-
writeJsonFileAtomically,
|
|
106
114
|
SecretCollector,
|
|
107
115
|
looksLikeTokenSegment,
|
|
108
116
|
AuthProfileError,
|
|
@@ -138,26 +146,20 @@ import {
|
|
|
138
146
|
settingsToExtension,
|
|
139
147
|
describeSettings,
|
|
140
148
|
describeChanges
|
|
141
|
-
} from "./main-
|
|
149
|
+
} from "./main-fkhwazsm.mjs";
|
|
142
150
|
import {
|
|
143
151
|
opencodeBrowserVersion2,
|
|
144
152
|
opencodeBrowserBuildId2
|
|
145
|
-
} from "./main-
|
|
153
|
+
} from "./main-ppz7sv9s.mjs";
|
|
146
154
|
import {
|
|
147
155
|
defaultJournalBaseDir,
|
|
148
156
|
makeJournalEntry,
|
|
149
157
|
appendJournalEntry,
|
|
150
158
|
startJournalRetention
|
|
151
|
-
} from "./main-
|
|
159
|
+
} from "./main-d7rbre73.mjs";
|
|
152
160
|
import {
|
|
153
161
|
createUpdateWatcher2
|
|
154
|
-
} from "./main-
|
|
155
|
-
import {
|
|
156
|
-
relayTokenQueryParam,
|
|
157
|
-
relayToken,
|
|
158
|
-
secretsEqual,
|
|
159
|
-
ensurePrivateDirectory
|
|
160
|
-
} from "./main-4bht27ry.mjs";
|
|
162
|
+
} from "./main-w5sta7hq.mjs";
|
|
161
163
|
|
|
162
164
|
// src/relay.ts
|
|
163
165
|
import http4 from "node:http";
|
|
@@ -858,9 +860,7 @@ function managedRelayLogPath(home = os.homedir()) {
|
|
|
858
860
|
function appendManagedRelayProcessLog(message, home = os.homedir()) {
|
|
859
861
|
try {
|
|
860
862
|
const logPath = managedRelayLogPath(home);
|
|
861
|
-
|
|
862
|
-
fs.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
863
|
-
fs.chmodSync(directory, 448);
|
|
863
|
+
ensurePrivateDirectorySync(path.dirname(logPath));
|
|
864
864
|
const entry = `${new Date().toISOString()} ${message.slice(0, maxEntryCharacters)}
|
|
865
865
|
`;
|
|
866
866
|
const stat = fs.statSync(logPath, { throwIfNoEntry: false });
|
|
@@ -1341,23 +1341,19 @@ class BrowserLinks {
|
|
|
1341
1341
|
id = `${base}-${n}`;
|
|
1342
1342
|
known[key] = { id, name };
|
|
1343
1343
|
try {
|
|
1344
|
-
|
|
1345
|
-
fs2.writeFileSync(this.file, `${JSON.stringify(known, null, 2)}
|
|
1346
|
-
`, { mode: 384 });
|
|
1344
|
+
writePrivateJsonFileSync(this.file, known, { ensureParent: true });
|
|
1347
1345
|
} catch {}
|
|
1348
1346
|
return id;
|
|
1349
1347
|
}
|
|
1350
1348
|
connect(options) {
|
|
1351
1349
|
const replaced = this.links.get(options.key);
|
|
1352
|
-
if (replaced)
|
|
1350
|
+
if (replaced)
|
|
1353
1351
|
this.disconnect(replaced.socket);
|
|
1354
|
-
replaced.rpc.rejectPending(new Error("Extension replaced"));
|
|
1355
|
-
}
|
|
1356
1352
|
const link = {
|
|
1357
1353
|
key: options.key,
|
|
1358
1354
|
id: this.identify(options.key, options.name),
|
|
1359
1355
|
name: options.name,
|
|
1360
|
-
rpc:
|
|
1356
|
+
rpc: new ExtensionRpc,
|
|
1361
1357
|
socket: options.socket,
|
|
1362
1358
|
generation: ++this.generation,
|
|
1363
1359
|
connectedAt: Date.now(),
|
|
@@ -1538,7 +1534,7 @@ class CdpRouter {
|
|
|
1538
1534
|
clientSessionId,
|
|
1539
1535
|
targetOwnerSessionId: target.opencodeBrowserSessionId,
|
|
1540
1536
|
targetOwner: target.owner,
|
|
1541
|
-
clientHasOwnedTarget: clientSessionId !== undefined && this.registry.listRootTargets().some((candidate) => candidate.opencodeBrowserSessionId === clientSessionId)
|
|
1537
|
+
clientHasOwnedTarget: clientSessionId !== undefined && target.opencodeBrowserSessionId === undefined && target.owner !== "user" && this.registry.listRootTargets().some((candidate) => candidate.opencodeBrowserSessionId === clientSessionId)
|
|
1542
1538
|
});
|
|
1543
1539
|
}
|
|
1544
1540
|
canSeeTab(client, tabId) {
|
|
@@ -7141,7 +7137,7 @@ async function waitForProgress(page, field, timeoutMs) {
|
|
|
7141
7137
|
return false;
|
|
7142
7138
|
}
|
|
7143
7139
|
async function clearSecretInputs(frames, fields = []) {
|
|
7144
|
-
const clearScript = (
|
|
7140
|
+
const clearScript = () => {
|
|
7145
7141
|
const own = (element) => {
|
|
7146
7142
|
const input = element;
|
|
7147
7143
|
if (!(input instanceof HTMLInputElement) || !input.value)
|
|
@@ -7154,7 +7150,7 @@ async function clearSecretInputs(frames, fields = []) {
|
|
|
7154
7150
|
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
7155
7151
|
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
7156
7152
|
};
|
|
7157
|
-
const all = [
|
|
7153
|
+
const all = [];
|
|
7158
7154
|
const walk = (root) => {
|
|
7159
7155
|
for (const element of Array.from(root.querySelectorAll("input"))) {
|
|
7160
7156
|
const input = element;
|
|
@@ -7182,7 +7178,7 @@ async function clearSecretInputs(frames, fields = []) {
|
|
|
7182
7178
|
for (const frame of new Set(frames)) {
|
|
7183
7179
|
if (frame.isDetached())
|
|
7184
7180
|
continue;
|
|
7185
|
-
await frame.evaluate(clearScript
|
|
7181
|
+
await frame.evaluate(clearScript).catch(() => {});
|
|
7186
7182
|
}
|
|
7187
7183
|
}
|
|
7188
7184
|
async function submit(read, field) {
|
|
@@ -7470,10 +7466,8 @@ var probeSelectors = [
|
|
|
7470
7466
|
"#challenge-running",
|
|
7471
7467
|
"#challenge-stage",
|
|
7472
7468
|
"#cf-challenge-running",
|
|
7473
|
-
"#cf-please-wait",
|
|
7474
7469
|
".cf-turnstile",
|
|
7475
7470
|
"#cf-error-details",
|
|
7476
|
-
"#cf-wrapper .cf-error-type",
|
|
7477
7471
|
"#sec-if-cpt-container",
|
|
7478
7472
|
"#sec-cpt-if",
|
|
7479
7473
|
"#sec-text-if",
|
|
@@ -13416,8 +13410,7 @@ var RelayLifecycleEvent = Schema8.TaggedUnion({
|
|
|
13416
13410
|
});
|
|
13417
13411
|
function appendRelayLifecycleEvent(filePath, event) {
|
|
13418
13412
|
const directory = path9.dirname(filePath);
|
|
13419
|
-
|
|
13420
|
-
fs8.chmodSync(directory, 448);
|
|
13413
|
+
ensurePrivateDirectorySync(directory);
|
|
13421
13414
|
const entry = `${JSON.stringify({ ...Schema8.encodeSync(RelayLifecycleEvent)(event), timestamp: new Date().toISOString() })}
|
|
13422
13415
|
`;
|
|
13423
13416
|
const file = fs8.openSync(filePath, "a+", 384);
|
|
@@ -13466,15 +13459,21 @@ class RelayShutdown {
|
|
|
13466
13459
|
get stopping() {
|
|
13467
13460
|
return State.$is("Stopping")(this.state) || State.$is("Closing")(this.state);
|
|
13468
13461
|
}
|
|
13469
|
-
|
|
13462
|
+
drainAndSettle() {
|
|
13470
13463
|
const control = this;
|
|
13471
13464
|
return Effect9.gen(function* () {
|
|
13472
|
-
control.state = State.Closing();
|
|
13473
13465
|
yield* Effect9.all([control.options.drain, control.idle.await], { concurrency: "unbounded" });
|
|
13474
13466
|
yield* control.idle.await;
|
|
13475
13467
|
yield* control.options.settle;
|
|
13476
13468
|
});
|
|
13477
13469
|
}
|
|
13470
|
+
close() {
|
|
13471
|
+
const control = this;
|
|
13472
|
+
return Effect9.gen(function* () {
|
|
13473
|
+
control.state = State.Closing();
|
|
13474
|
+
yield* control.drainAndSettle();
|
|
13475
|
+
});
|
|
13476
|
+
}
|
|
13478
13477
|
track(effect) {
|
|
13479
13478
|
const control = this;
|
|
13480
13479
|
return Effect9.acquireUseRelease(Effect9.suspend(() => {
|
|
@@ -13516,9 +13515,7 @@ class RelayShutdown {
|
|
|
13516
13515
|
const busy = control.options.busy();
|
|
13517
13516
|
if (busy)
|
|
13518
13517
|
return yield* control.busyError(busy);
|
|
13519
|
-
yield*
|
|
13520
|
-
yield* control.idle.await;
|
|
13521
|
-
yield* control.options.settle;
|
|
13518
|
+
yield* control.drainAndSettle();
|
|
13522
13519
|
const remaining = control.options.busy();
|
|
13523
13520
|
if (remaining)
|
|
13524
13521
|
return yield* control.busyError(remaining);
|
|
@@ -14295,7 +14292,7 @@ function guardStorageAccess(context) {
|
|
|
14295
14292
|
});
|
|
14296
14293
|
if (outside === undefined)
|
|
14297
14294
|
return null;
|
|
14298
|
-
return `Browse blocked ${context.method}: site storage can only be used for the hosts of this session's attached pages (${hosts
|
|
14295
|
+
return `Browse blocked ${context.method}: site storage can only be used for the hosts of this session's attached pages (${formatAllowedHosts(hosts)}), not ${outside}. Set ${allowAllStorageEnvironmentVariable}=1 on the relay to allow it.`;
|
|
14299
14296
|
}
|
|
14300
14297
|
var restrictedNavigationSchemes = new Set([
|
|
14301
14298
|
"file:",
|
|
@@ -14358,13 +14355,16 @@ function cookieDomainOf(cookie) {
|
|
|
14358
14355
|
}
|
|
14359
14356
|
return typeof domain === "string" ? domain : undefined;
|
|
14360
14357
|
}
|
|
14358
|
+
function formatAllowedHosts(hosts) {
|
|
14359
|
+
return hosts.length > 0 ? hosts.join(", ") : "none";
|
|
14360
|
+
}
|
|
14361
14361
|
function guardCookieWrite(context) {
|
|
14362
14362
|
const cookies = context.method === "Network.setCookie" ? [context.params] : Array.isArray(context.params?.cookies) ? context.params.cookies : [];
|
|
14363
14363
|
const hosts = pageHosts(context.pageUrls?.() ?? []);
|
|
14364
14364
|
for (const cookie of cookies) {
|
|
14365
14365
|
const domain = cookieDomainOf(cookie);
|
|
14366
14366
|
if (!domain || !hosts.some((host) => cookieAppliesToHost(domain, host))) {
|
|
14367
|
-
return `Browse blocked ${context.method}: cookies can only be set for the hosts of this session's attached pages (${hosts
|
|
14367
|
+
return `Browse blocked ${context.method}: cookies can only be set for the hosts of this session's attached pages (${formatAllowedHosts(hosts)}), not ${domain ?? "a cookie without a domain or url"}. Set ${allowAllCookiesEnvironmentVariable}=1 on the relay to allow it.`;
|
|
14368
14368
|
}
|
|
14369
14369
|
}
|
|
14370
14370
|
return null;
|
|
@@ -14398,7 +14398,7 @@ function guardCdpMethod(context) {
|
|
|
14398
14398
|
const hosts = pageHosts(context.pageUrls?.() ?? []);
|
|
14399
14399
|
const host = typeof url === "string" ? pageHosts([url])[0] : undefined;
|
|
14400
14400
|
if (host === undefined || !hosts.includes(host)) {
|
|
14401
|
-
return `Browse blocked Network.loadNetworkResource: it loads URLs with the user's credentials outside the page's same-origin policy, so only the hosts of this session's attached pages (${hosts
|
|
14401
|
+
return `Browse blocked Network.loadNetworkResource: it loads URLs with the user's credentials outside the page's same-origin policy, so only the hosts of this session's attached pages (${formatAllowedHosts(hosts)}) are allowed. Set ${allowAllStorageEnvironmentVariable}=1 on the relay to allow it.`;
|
|
14402
14402
|
}
|
|
14403
14403
|
}
|
|
14404
14404
|
if (context.readOnly && readOnlyBlockedPrefixes.some((prefix) => context.method.startsWith(prefix))) {
|
|
@@ -8,24 +8,23 @@ import {
|
|
|
8
8
|
compareVersions,
|
|
9
9
|
readCurrent,
|
|
10
10
|
writeCurrent,
|
|
11
|
-
readState,
|
|
12
11
|
updateState,
|
|
13
12
|
npmRuntime,
|
|
14
|
-
|
|
13
|
+
effectiveMode,
|
|
15
14
|
registryUrl,
|
|
16
15
|
fetchPublished,
|
|
17
16
|
installVersion,
|
|
18
17
|
pruneVersions,
|
|
19
18
|
switchVersion
|
|
20
|
-
} from "./main-
|
|
19
|
+
} from "./main-ha5bnd77.mjs";
|
|
21
20
|
import {
|
|
22
21
|
Service,
|
|
23
22
|
layerFetch,
|
|
24
23
|
restartRelay,
|
|
25
24
|
startManagedRelay
|
|
26
|
-
} from "./main-
|
|
27
|
-
import"./main-
|
|
28
|
-
import"./main-
|
|
25
|
+
} from "./main-jjny7bmm.mjs";
|
|
26
|
+
import"./main-9y22cffn.mjs";
|
|
27
|
+
import"./main-ppz7sv9s.mjs";
|
|
29
28
|
|
|
30
29
|
// src/runtime-update.ts
|
|
31
30
|
import { Effect } from "effect";
|
|
@@ -129,7 +128,7 @@ async function runNpmUpdate(args, layout) {
|
|
|
129
128
|
const current = readCurrent(lay);
|
|
130
129
|
const refused = await switchTo(lay, published.version, { previous: current.version, force: args.includes("--force") });
|
|
131
130
|
if (refused) {
|
|
132
|
-
const automatic = (
|
|
131
|
+
const automatic = effectiveMode(lay) === "on";
|
|
133
132
|
log(`! Installed ${published.version}, but the relay didn't restart (${refused}).`);
|
|
134
133
|
log(automatic ? " It switches to the new version by itself once no agent is using the browser." : ` When no agent is using the browser, run \`${cliCommand("update")}\` again.`);
|
|
135
134
|
return true;
|
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
installVersion,
|
|
22
22
|
pruneVersions,
|
|
23
23
|
switchVersion
|
|
24
|
-
} from "./main-
|
|
24
|
+
} from "./main-ha5bnd77.mjs";
|
|
25
|
+
import {
|
|
26
|
+
relayAuthorization
|
|
27
|
+
} from "./main-9y22cffn.mjs";
|
|
25
28
|
import {
|
|
26
29
|
pairingCodeTtlMs,
|
|
27
30
|
bundledPairingCodeTtlMs,
|
|
@@ -38,13 +41,10 @@ import {
|
|
|
38
41
|
parseHostname,
|
|
39
42
|
readRelayConfig,
|
|
40
43
|
writeRelayConfig
|
|
41
|
-
} from "./main-
|
|
44
|
+
} from "./main-0egy8naa.mjs";
|
|
42
45
|
import {
|
|
43
46
|
opencodeBrowserVersion2
|
|
44
|
-
} from "./main-
|
|
45
|
-
import {
|
|
46
|
-
relayAuthorization
|
|
47
|
-
} from "./main-4bht27ry.mjs";
|
|
47
|
+
} from "./main-ppz7sv9s.mjs";
|
|
48
48
|
import { createRequire } from "node:module";
|
|
49
49
|
var __create = Object.create;
|
|
50
50
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -11310,7 +11310,7 @@ async function runSetup(command, args) {
|
|
|
11310
11310
|
if (command === "set")
|
|
11311
11311
|
return set(args);
|
|
11312
11312
|
if (command === "rollback") {
|
|
11313
|
-
const { runRollback } = await import("./runtime-update-
|
|
11313
|
+
const { runRollback } = await import("./runtime-update-8wte78jj.mjs");
|
|
11314
11314
|
return runRollback(args);
|
|
11315
11315
|
}
|
|
11316
11316
|
}
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
updateNotice2,
|
|
5
5
|
createUpdateWatcher2,
|
|
6
6
|
runUpdateCommand2
|
|
7
|
-
} from "./main-
|
|
8
|
-
import"./main-
|
|
7
|
+
} from "./main-w5sta7hq.mjs";
|
|
8
|
+
import"./main-ha5bnd77.mjs";
|
|
9
9
|
export {
|
|
10
10
|
createUpdateWatcher2 as createUpdateWatcher,
|
|
11
11
|
formatUpdateNotice2 as formatUpdateNotice,
|
package/package.json
CHANGED
package/dist/main-4bht27ry.mjs
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
dataRoot
|
|
3
|
-
} from "./main-g5mke6rn.mjs";
|
|
4
|
-
|
|
5
|
-
// src/relay-secrets.ts
|
|
6
|
-
import crypto from "node:crypto";
|
|
7
|
-
import fs from "node:fs";
|
|
8
|
-
import path from "node:path";
|
|
9
|
-
var relayTokenQueryParam = "opencodeBrowserToken";
|
|
10
|
-
var tokenPattern = /^[A-Za-z0-9_-]{43}$/;
|
|
11
|
-
function relayTokenPath(root = dataRoot()) {
|
|
12
|
-
return path.join(root, "relay-token");
|
|
13
|
-
}
|
|
14
|
-
function relayToken(root = dataRoot()) {
|
|
15
|
-
return readOrCreateSecret(relayTokenPath(root), () => crypto.randomBytes(32).toString("base64url"), (value) => tokenPattern.test(value));
|
|
16
|
-
}
|
|
17
|
-
function relayAuthorization(root = dataRoot()) {
|
|
18
|
-
return `Bearer ${relayToken(root)}`;
|
|
19
|
-
}
|
|
20
|
-
function secretsEqual(expected, actual) {
|
|
21
|
-
if (actual === undefined)
|
|
22
|
-
return false;
|
|
23
|
-
const a = crypto.createHash("sha256").update(expected).digest();
|
|
24
|
-
const b = crypto.createHash("sha256").update(actual).digest();
|
|
25
|
-
return crypto.timingSafeEqual(a, b) && expected.length === actual.length;
|
|
26
|
-
}
|
|
27
|
-
function readOrCreateSecret(file, generate, valid) {
|
|
28
|
-
const existing = readSecret(file);
|
|
29
|
-
if (existing !== undefined && valid(existing))
|
|
30
|
-
return existing;
|
|
31
|
-
ensurePrivateDirectory(path.dirname(file));
|
|
32
|
-
const temporary = `${file}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
33
|
-
fs.writeFileSync(temporary, `${generate()}
|
|
34
|
-
`, { mode: 384 });
|
|
35
|
-
try {
|
|
36
|
-
if (existing === undefined) {
|
|
37
|
-
try {
|
|
38
|
-
fs.linkSync(temporary, file);
|
|
39
|
-
} catch (error) {
|
|
40
|
-
if (error.code !== "EEXIST")
|
|
41
|
-
throw error;
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
fs.renameSync(temporary, file);
|
|
45
|
-
}
|
|
46
|
-
} finally {
|
|
47
|
-
fs.rmSync(temporary, { force: true });
|
|
48
|
-
}
|
|
49
|
-
const created = readSecret(file);
|
|
50
|
-
if (created === undefined || !valid(created))
|
|
51
|
-
throw new Error(`Could not create ${file}`);
|
|
52
|
-
return created;
|
|
53
|
-
}
|
|
54
|
-
function readSecret(file) {
|
|
55
|
-
try {
|
|
56
|
-
const stat = fs.statSync(file);
|
|
57
|
-
if (process.platform !== "win32" && (stat.mode & 63) !== 0)
|
|
58
|
-
fs.chmodSync(file, 384);
|
|
59
|
-
return fs.readFileSync(file, "utf8").trim();
|
|
60
|
-
} catch (error) {
|
|
61
|
-
if (error.code === "ENOENT")
|
|
62
|
-
return;
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
function ensurePrivateDirectory(directory = dataRoot()) {
|
|
67
|
-
fs.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
68
|
-
if (process.platform !== "win32")
|
|
69
|
-
fs.chmodSync(directory, 448);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export { relayTokenQueryParam, relayToken, relayAuthorization, secretsEqual, ensurePrivateDirectory };
|
package/dist/main-y7c1atbf.mjs
DELETED