viyv-browser-mcp 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +255 -117
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2988,7 +2988,7 @@ var require_compile = __commonJS({
|
|
|
2988
2988
|
const schOrFunc = root.refs[ref];
|
|
2989
2989
|
if (schOrFunc)
|
|
2990
2990
|
return schOrFunc;
|
|
2991
|
-
let _sch =
|
|
2991
|
+
let _sch = resolve4.call(this, root, ref);
|
|
2992
2992
|
if (_sch === void 0) {
|
|
2993
2993
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
2994
2994
|
const { schemaId } = this.opts;
|
|
@@ -3015,7 +3015,7 @@ var require_compile = __commonJS({
|
|
|
3015
3015
|
function sameSchemaEnv(s1, s2) {
|
|
3016
3016
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3017
3017
|
}
|
|
3018
|
-
function
|
|
3018
|
+
function resolve4(root, ref) {
|
|
3019
3019
|
let sch;
|
|
3020
3020
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3021
3021
|
ref = sch;
|
|
@@ -3590,7 +3590,7 @@ var require_fast_uri = __commonJS({
|
|
|
3590
3590
|
}
|
|
3591
3591
|
return uri;
|
|
3592
3592
|
}
|
|
3593
|
-
function
|
|
3593
|
+
function resolve4(baseURI, relativeURI, options) {
|
|
3594
3594
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3595
3595
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3596
3596
|
schemelessOptions.skipEscape = true;
|
|
@@ -3817,7 +3817,7 @@ var require_fast_uri = __commonJS({
|
|
|
3817
3817
|
var fastUri = {
|
|
3818
3818
|
SCHEMES,
|
|
3819
3819
|
normalize: normalize2,
|
|
3820
|
-
resolve:
|
|
3820
|
+
resolve: resolve4,
|
|
3821
3821
|
resolveComponent,
|
|
3822
3822
|
equal,
|
|
3823
3823
|
serialize,
|
|
@@ -11452,10 +11452,10 @@ var require_raw_body = __commonJS({
|
|
|
11452
11452
|
if (done) {
|
|
11453
11453
|
return readStream(stream, encoding, length, limit, wrap(done));
|
|
11454
11454
|
}
|
|
11455
|
-
return new Promise(function executor(
|
|
11455
|
+
return new Promise(function executor(resolve4, reject) {
|
|
11456
11456
|
readStream(stream, encoding, length, limit, function onRead(err, buf) {
|
|
11457
11457
|
if (err) return reject(err);
|
|
11458
|
-
|
|
11458
|
+
resolve4(buf);
|
|
11459
11459
|
});
|
|
11460
11460
|
});
|
|
11461
11461
|
}
|
|
@@ -11695,7 +11695,7 @@ var require_content_type = __commonJS({
|
|
|
11695
11695
|
|
|
11696
11696
|
// src/native-host/bridge.ts
|
|
11697
11697
|
import { randomUUID } from "crypto";
|
|
11698
|
-
import { readFileSync as
|
|
11698
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
11699
11699
|
import { createServer as createServer2 } from "net";
|
|
11700
11700
|
import { join as join2 } from "path";
|
|
11701
11701
|
|
|
@@ -11840,59 +11840,156 @@ function shouldBroadcastClosing(reason) {
|
|
|
11840
11840
|
}
|
|
11841
11841
|
}
|
|
11842
11842
|
|
|
11843
|
+
// ../shared/dist/util/semver.js
|
|
11844
|
+
function compareSemver(a, b) {
|
|
11845
|
+
const pa = a.split(".").map((s) => Number.parseInt(s, 10));
|
|
11846
|
+
const pb = b.split(".").map((s) => Number.parseInt(s, 10));
|
|
11847
|
+
for (let i = 0; i < 3; i++) {
|
|
11848
|
+
const ai = Number.isFinite(pa[i]) ? pa[i] : 0;
|
|
11849
|
+
const bi = Number.isFinite(pb[i]) ? pb[i] : 0;
|
|
11850
|
+
const diff = ai - bi;
|
|
11851
|
+
if (diff !== 0)
|
|
11852
|
+
return diff;
|
|
11853
|
+
}
|
|
11854
|
+
return 0;
|
|
11855
|
+
}
|
|
11856
|
+
|
|
11843
11857
|
// src/native-host-updater.ts
|
|
11844
|
-
import {
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
renameSync,
|
|
11851
|
-
unlinkSync
|
|
11852
|
-
} from "fs";
|
|
11858
|
+
import { chmodSync, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
11859
|
+
import { resolve as resolve2 } from "path";
|
|
11860
|
+
import { fileURLToPath } from "url";
|
|
11861
|
+
|
|
11862
|
+
// src/native-host/deployment-state.ts
|
|
11863
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
11853
11864
|
import { homedir } from "os";
|
|
11854
11865
|
import { resolve } from "path";
|
|
11855
|
-
|
|
11866
|
+
function getNativeHostDir() {
|
|
11867
|
+
return resolve(homedir(), ".viyv-browser", "native-host");
|
|
11868
|
+
}
|
|
11869
|
+
function getDeploymentBinaryPath() {
|
|
11870
|
+
return resolve(getNativeHostDir(), "index.js");
|
|
11871
|
+
}
|
|
11872
|
+
function getDeploymentVersionPath() {
|
|
11873
|
+
return resolve(getNativeHostDir(), "version");
|
|
11874
|
+
}
|
|
11875
|
+
var SEMVER_CORE = /^\d+\.\d+\.\d+/;
|
|
11876
|
+
function readDeploymentState() {
|
|
11877
|
+
const versionPath = getDeploymentVersionPath();
|
|
11878
|
+
if (!existsSync(versionPath)) {
|
|
11879
|
+
return { version: null };
|
|
11880
|
+
}
|
|
11881
|
+
try {
|
|
11882
|
+
const raw = readFileSync(versionPath, "utf-8").trim();
|
|
11883
|
+
if (!raw || !SEMVER_CORE.test(raw)) {
|
|
11884
|
+
return { version: null };
|
|
11885
|
+
}
|
|
11886
|
+
return { version: raw };
|
|
11887
|
+
} catch {
|
|
11888
|
+
return { version: null };
|
|
11889
|
+
}
|
|
11890
|
+
}
|
|
11891
|
+
function writeDeploymentVersion(version2) {
|
|
11892
|
+
const dir = getNativeHostDir();
|
|
11893
|
+
mkdirSync(dir, { recursive: true });
|
|
11894
|
+
const target = getDeploymentVersionPath();
|
|
11895
|
+
const tmp = resolve(dir, `version.tmp.${process.pid}`);
|
|
11896
|
+
try {
|
|
11897
|
+
writeFileSync(tmp, `${version2}
|
|
11898
|
+
`, "utf-8");
|
|
11899
|
+
renameSync(tmp, target);
|
|
11900
|
+
} catch (err) {
|
|
11901
|
+
try {
|
|
11902
|
+
unlinkSync(tmp);
|
|
11903
|
+
} catch {
|
|
11904
|
+
}
|
|
11905
|
+
throw err;
|
|
11906
|
+
}
|
|
11907
|
+
}
|
|
11908
|
+
|
|
11909
|
+
// src/native-host/sync-policy.ts
|
|
11910
|
+
function decideSyncAction(state, selfVersion) {
|
|
11911
|
+
if (state.version === null) {
|
|
11912
|
+
return {
|
|
11913
|
+
shouldSync: true,
|
|
11914
|
+
reason: "no-deploy-version",
|
|
11915
|
+
deployedVersion: null,
|
|
11916
|
+
selfVersion
|
|
11917
|
+
};
|
|
11918
|
+
}
|
|
11919
|
+
const cmp = compareSemver(selfVersion, state.version);
|
|
11920
|
+
if (cmp > 0) {
|
|
11921
|
+
return {
|
|
11922
|
+
shouldSync: true,
|
|
11923
|
+
reason: "upgrade",
|
|
11924
|
+
deployedVersion: state.version,
|
|
11925
|
+
selfVersion
|
|
11926
|
+
};
|
|
11927
|
+
}
|
|
11928
|
+
if (cmp === 0) {
|
|
11929
|
+
return {
|
|
11930
|
+
shouldSync: true,
|
|
11931
|
+
reason: "same-version-idempotent",
|
|
11932
|
+
deployedVersion: state.version,
|
|
11933
|
+
selfVersion
|
|
11934
|
+
};
|
|
11935
|
+
}
|
|
11936
|
+
return {
|
|
11937
|
+
shouldSync: false,
|
|
11938
|
+
reason: "avoid-downgrade",
|
|
11939
|
+
deployedVersion: state.version,
|
|
11940
|
+
selfVersion
|
|
11941
|
+
};
|
|
11942
|
+
}
|
|
11943
|
+
|
|
11944
|
+
// src/native-host-updater.ts
|
|
11856
11945
|
var PKG_VERSION = (() => {
|
|
11857
|
-
if (true) return "0.
|
|
11946
|
+
if (true) return "0.11.0";
|
|
11858
11947
|
try {
|
|
11859
11948
|
const here = fileURLToPath(import.meta.url);
|
|
11860
|
-
const pkgPath =
|
|
11861
|
-
const pkg = JSON.parse(
|
|
11949
|
+
const pkgPath = resolve2(here, "..", "..", "package.json");
|
|
11950
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
11862
11951
|
return pkg.version ?? "0.0.0-test";
|
|
11863
11952
|
} catch {
|
|
11864
11953
|
return "0.0.0-test";
|
|
11865
11954
|
}
|
|
11866
11955
|
})();
|
|
11867
|
-
var NATIVE_HOST_DIR = resolve(homedir(), ".viyv-browser", "native-host");
|
|
11868
11956
|
function getSourceBinaryPath() {
|
|
11869
11957
|
return fileURLToPath(import.meta.url);
|
|
11870
11958
|
}
|
|
11871
11959
|
function getNativeHostBinaryPath() {
|
|
11872
|
-
return
|
|
11960
|
+
return getDeploymentBinaryPath();
|
|
11873
11961
|
}
|
|
11874
11962
|
function isNativeHostDeployed() {
|
|
11875
|
-
return
|
|
11963
|
+
return existsSync2(getNativeHostBinaryPath());
|
|
11876
11964
|
}
|
|
11877
11965
|
function syncNativeHostBinary() {
|
|
11878
11966
|
const source = getSourceBinaryPath();
|
|
11879
|
-
if (!
|
|
11967
|
+
if (!existsSync2(source)) {
|
|
11880
11968
|
throw new Error(`Source binary not found: ${source}`);
|
|
11881
11969
|
}
|
|
11882
|
-
|
|
11970
|
+
const dir = getNativeHostDir();
|
|
11971
|
+
mkdirSync2(dir, { recursive: true });
|
|
11883
11972
|
const target = getNativeHostBinaryPath();
|
|
11884
|
-
const tmp =
|
|
11973
|
+
const tmp = resolve2(dir, `index.js.tmp.${process.pid}`);
|
|
11885
11974
|
try {
|
|
11886
11975
|
copyFileSync(source, tmp);
|
|
11887
11976
|
chmodSync(tmp, 493);
|
|
11888
|
-
|
|
11977
|
+
renameSync2(tmp, target);
|
|
11889
11978
|
} catch (err) {
|
|
11890
11979
|
try {
|
|
11891
|
-
|
|
11980
|
+
unlinkSync2(tmp);
|
|
11892
11981
|
} catch {
|
|
11893
11982
|
}
|
|
11894
11983
|
throw err;
|
|
11895
11984
|
}
|
|
11985
|
+
writeDeploymentVersion(PKG_VERSION);
|
|
11986
|
+
}
|
|
11987
|
+
function syncNativeHostBinaryIfNeeded() {
|
|
11988
|
+
const decision = decideSyncAction(readDeploymentState(), PKG_VERSION);
|
|
11989
|
+
if (decision.shouldSync) {
|
|
11990
|
+
syncNativeHostBinary();
|
|
11991
|
+
}
|
|
11992
|
+
return decision;
|
|
11896
11993
|
}
|
|
11897
11994
|
function shouldUpdateBridge(bridgeVersion) {
|
|
11898
11995
|
return compareSemver(PKG_VERSION, bridgeVersion) > 0;
|
|
@@ -11900,20 +11997,11 @@ function shouldUpdateBridge(bridgeVersion) {
|
|
|
11900
11997
|
function getPackageVersion() {
|
|
11901
11998
|
return PKG_VERSION;
|
|
11902
11999
|
}
|
|
11903
|
-
function compareSemver(a, b) {
|
|
11904
|
-
const pa = a.split(".").map(Number);
|
|
11905
|
-
const pb = b.split(".").map(Number);
|
|
11906
|
-
for (let i = 0; i < 3; i++) {
|
|
11907
|
-
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
11908
|
-
if (diff !== 0) return diff;
|
|
11909
|
-
}
|
|
11910
|
-
return 0;
|
|
11911
|
-
}
|
|
11912
12000
|
|
|
11913
12001
|
// src/native-host/bridge-control.ts
|
|
11914
12002
|
import { randomBytes } from "crypto";
|
|
11915
12003
|
import { createServer } from "net";
|
|
11916
|
-
import { chmodSync as chmodSync2, mkdirSync as
|
|
12004
|
+
import { chmodSync as chmodSync2, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
11917
12005
|
import { dirname } from "path";
|
|
11918
12006
|
var LOG_PREFIX = "[viyv-browser:native-host:control]";
|
|
11919
12007
|
function startBridgeControl(opts) {
|
|
@@ -11923,9 +12011,9 @@ function startBridgeControl(opts) {
|
|
|
11923
12011
|
const { deps, onError } = opts;
|
|
11924
12012
|
let cookie;
|
|
11925
12013
|
try {
|
|
11926
|
-
|
|
12014
|
+
mkdirSync3(dirname(cookiePath), { recursive: true });
|
|
11927
12015
|
cookie = randomBytes(BRIDGE.CONTROL_COOKIE_BYTES);
|
|
11928
|
-
|
|
12016
|
+
writeFileSync2(cookiePath, cookie.toString("hex"), { mode: 384 });
|
|
11929
12017
|
try {
|
|
11930
12018
|
chmodSync2(cookiePath, 384);
|
|
11931
12019
|
} catch {
|
|
@@ -12063,7 +12151,7 @@ function startBridgeControl(opts) {
|
|
|
12063
12151
|
}
|
|
12064
12152
|
|
|
12065
12153
|
// src/native-host/bridge-relay.ts
|
|
12066
|
-
import { readFileSync as
|
|
12154
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
12067
12155
|
import { createConnection } from "net";
|
|
12068
12156
|
import { join } from "path";
|
|
12069
12157
|
|
|
@@ -12165,7 +12253,7 @@ function readProfileIdFromEnv() {
|
|
|
12165
12253
|
const dir = process.env.VIYV_USER_DATA_DIR;
|
|
12166
12254
|
if (!dir) return null;
|
|
12167
12255
|
try {
|
|
12168
|
-
const raw =
|
|
12256
|
+
const raw = readFileSync3(join(dir, "viyv-profile.id"), "utf8").trim();
|
|
12169
12257
|
return raw || null;
|
|
12170
12258
|
} catch {
|
|
12171
12259
|
return null;
|
|
@@ -12841,7 +12929,7 @@ function startBridge(options) {
|
|
|
12841
12929
|
const primaryUserDataDir = process.env.VIYV_USER_DATA_DIR;
|
|
12842
12930
|
if (primaryUserDataDir) {
|
|
12843
12931
|
try {
|
|
12844
|
-
const raw =
|
|
12932
|
+
const raw = readFileSync4(join2(primaryUserDataDir, "viyv-profile.id"), "utf8").trim();
|
|
12845
12933
|
if (raw) {
|
|
12846
12934
|
setProfileId(primaryChromeId, raw);
|
|
12847
12935
|
process.stderr.write(
|
|
@@ -12874,7 +12962,7 @@ function startBridge(options) {
|
|
|
12874
12962
|
|
|
12875
12963
|
// src/server.ts
|
|
12876
12964
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
12877
|
-
import { existsSync as
|
|
12965
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
12878
12966
|
import http from "http";
|
|
12879
12967
|
import { dirname as dirname2 } from "path";
|
|
12880
12968
|
|
|
@@ -24952,7 +25040,7 @@ var Protocol = class {
|
|
|
24952
25040
|
return;
|
|
24953
25041
|
}
|
|
24954
25042
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
24955
|
-
await new Promise((
|
|
25043
|
+
await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
|
|
24956
25044
|
options?.signal?.throwIfAborted();
|
|
24957
25045
|
}
|
|
24958
25046
|
} catch (error2) {
|
|
@@ -24969,7 +25057,7 @@ var Protocol = class {
|
|
|
24969
25057
|
*/
|
|
24970
25058
|
request(request, resultSchema, options) {
|
|
24971
25059
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
24972
|
-
return new Promise((
|
|
25060
|
+
return new Promise((resolve4, reject) => {
|
|
24973
25061
|
const earlyReject = (error2) => {
|
|
24974
25062
|
reject(error2);
|
|
24975
25063
|
};
|
|
@@ -25047,7 +25135,7 @@ var Protocol = class {
|
|
|
25047
25135
|
if (!parseResult.success) {
|
|
25048
25136
|
reject(parseResult.error);
|
|
25049
25137
|
} else {
|
|
25050
|
-
|
|
25138
|
+
resolve4(parseResult.data);
|
|
25051
25139
|
}
|
|
25052
25140
|
} catch (error2) {
|
|
25053
25141
|
reject(error2);
|
|
@@ -25308,12 +25396,12 @@ var Protocol = class {
|
|
|
25308
25396
|
}
|
|
25309
25397
|
} catch {
|
|
25310
25398
|
}
|
|
25311
|
-
return new Promise((
|
|
25399
|
+
return new Promise((resolve4, reject) => {
|
|
25312
25400
|
if (signal.aborted) {
|
|
25313
25401
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
25314
25402
|
return;
|
|
25315
25403
|
}
|
|
25316
|
-
const timeoutId = setTimeout(
|
|
25404
|
+
const timeoutId = setTimeout(resolve4, interval);
|
|
25317
25405
|
signal.addEventListener("abort", () => {
|
|
25318
25406
|
clearTimeout(timeoutId);
|
|
25319
25407
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -26272,7 +26360,7 @@ var McpServer = class {
|
|
|
26272
26360
|
let task = createTaskResult.task;
|
|
26273
26361
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
26274
26362
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
26275
|
-
await new Promise((
|
|
26363
|
+
await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
|
|
26276
26364
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
26277
26365
|
if (!updatedTask) {
|
|
26278
26366
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -27060,12 +27148,12 @@ var StdioServerTransport = class {
|
|
|
27060
27148
|
this.onclose?.();
|
|
27061
27149
|
}
|
|
27062
27150
|
send(message2) {
|
|
27063
|
-
return new Promise((
|
|
27151
|
+
return new Promise((resolve4) => {
|
|
27064
27152
|
const json = serializeMessage(message2);
|
|
27065
27153
|
if (this._stdout.write(json)) {
|
|
27066
|
-
|
|
27154
|
+
resolve4();
|
|
27067
27155
|
} else {
|
|
27068
|
-
this._stdout.once("drain",
|
|
27156
|
+
this._stdout.once("drain", resolve4);
|
|
27069
27157
|
}
|
|
27070
27158
|
});
|
|
27071
27159
|
}
|
|
@@ -27479,7 +27567,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
27479
27567
|
});
|
|
27480
27568
|
if (!chunk) {
|
|
27481
27569
|
if (i === 1) {
|
|
27482
|
-
await new Promise((
|
|
27570
|
+
await new Promise((resolve4) => setTimeout(resolve4));
|
|
27483
27571
|
maxReadCount = 3;
|
|
27484
27572
|
continue;
|
|
27485
27573
|
}
|
|
@@ -27961,9 +28049,9 @@ data:
|
|
|
27961
28049
|
const initRequest = messages.find((m) => isInitializeRequest(m));
|
|
27962
28050
|
const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
|
|
27963
28051
|
if (this._enableJsonResponse) {
|
|
27964
|
-
return new Promise((
|
|
28052
|
+
return new Promise((resolve4) => {
|
|
27965
28053
|
this._streamMapping.set(streamId, {
|
|
27966
|
-
resolveJson:
|
|
28054
|
+
resolveJson: resolve4,
|
|
27967
28055
|
cleanup: () => {
|
|
27968
28056
|
this._streamMapping.delete(streamId);
|
|
27969
28057
|
}
|
|
@@ -28485,11 +28573,11 @@ var BridgeClient = class {
|
|
|
28485
28573
|
* is exhausted or `timeout` if the handshake takes too long.
|
|
28486
28574
|
*/
|
|
28487
28575
|
enqueueToolCall(line) {
|
|
28488
|
-
return new Promise((
|
|
28576
|
+
return new Promise((resolve4, reject) => {
|
|
28489
28577
|
if (this.state === "ready" && this.socket && !this.socket.destroyed) {
|
|
28490
28578
|
try {
|
|
28491
28579
|
this.socket.write(line.endsWith(LINE_TERMINATOR) ? line : line + LINE_TERMINATOR);
|
|
28492
|
-
|
|
28580
|
+
resolve4();
|
|
28493
28581
|
} catch (err) {
|
|
28494
28582
|
reject({ reason: "write-failed", detail: err instanceof Error ? err.message : String(err) });
|
|
28495
28583
|
}
|
|
@@ -28498,7 +28586,7 @@ var BridgeClient = class {
|
|
|
28498
28586
|
const enqueued = this.queue.enqueue({
|
|
28499
28587
|
payload: {
|
|
28500
28588
|
line: line.endsWith(LINE_TERMINATOR) ? line : line + LINE_TERMINATOR,
|
|
28501
|
-
resolve:
|
|
28589
|
+
resolve: resolve4,
|
|
28502
28590
|
reject
|
|
28503
28591
|
},
|
|
28504
28592
|
onFlush: (entry) => {
|
|
@@ -28677,6 +28765,20 @@ function toolCallRejectionToErrorCode(rej) {
|
|
|
28677
28765
|
}
|
|
28678
28766
|
}
|
|
28679
28767
|
|
|
28768
|
+
// src/bridge-protocol/shutdown-request-gate.ts
|
|
28769
|
+
var SHUTDOWN_REQUEST_COOLDOWN_MS = 3e4;
|
|
28770
|
+
function createShutdownGateState() {
|
|
28771
|
+
return { lastSentAt: null, lastVersion: null };
|
|
28772
|
+
}
|
|
28773
|
+
function shouldSendShutdownRequest(state, observedVersion, now, cooldownMs = SHUTDOWN_REQUEST_COOLDOWN_MS) {
|
|
28774
|
+
if (state.lastSentAt === null) return true;
|
|
28775
|
+
if (state.lastVersion !== observedVersion) return true;
|
|
28776
|
+
return now - state.lastSentAt >= cooldownMs;
|
|
28777
|
+
}
|
|
28778
|
+
function markSent(state, version2, now) {
|
|
28779
|
+
return { lastSentAt: now, lastVersion: version2 };
|
|
28780
|
+
}
|
|
28781
|
+
|
|
28680
28782
|
// ../shared/dist/bearer-equals.js
|
|
28681
28783
|
import { timingSafeEqual } from "crypto";
|
|
28682
28784
|
function bearerEquals(header, expectedToken) {
|
|
@@ -33585,13 +33687,17 @@ var smBundleSchema = external_exports.object({
|
|
|
33585
33687
|
fetches: external_exports.array(external_exports.object({ fetch_id: external_exports.string() }).passthrough()),
|
|
33586
33688
|
scenario: external_exports.object({ scenario_id: external_exports.string() }).passthrough()
|
|
33587
33689
|
}).passthrough();
|
|
33690
|
+
var smRuntimeParamsSchema = external_exports.record(external_exports.union([external_exports.string(), external_exports.array(external_exports.string())])).optional();
|
|
33588
33691
|
var smRunInlineOptionsSchema = external_exports.object({
|
|
33589
33692
|
tabId: external_exports.coerce.number().optional(),
|
|
33590
33693
|
tabStrategy: external_exports.enum(["reuse", "create", "create-then-close"]).optional(),
|
|
33591
33694
|
chromeProfile: external_exports.string().optional(),
|
|
33592
33695
|
timeoutMs: external_exports.coerce.number().int().positive().optional(),
|
|
33593
33696
|
abortSignal: external_exports.string().optional(),
|
|
33594
|
-
dryRun: external_exports.boolean().optional()
|
|
33697
|
+
dryRun: external_exports.boolean().optional(),
|
|
33698
|
+
// F3: scenario-wide cartesian-product cap. Omitted = runtime default
|
|
33699
|
+
// (SAFETY.DEFAULT_MAX_TOTAL_ITERATIONS = 1000). Batch callers override.
|
|
33700
|
+
maxTotalIterations: external_exports.coerce.number().int().positive().optional()
|
|
33595
33701
|
}).optional();
|
|
33596
33702
|
var smRunInlineTool = {
|
|
33597
33703
|
name: "sm_run_inline",
|
|
@@ -33602,8 +33708,12 @@ var smRunInlineTool = {
|
|
|
33602
33708
|
related: SM_RUN_INLINE_RELATED,
|
|
33603
33709
|
inputSchema: external_exports.object({
|
|
33604
33710
|
bundle: smBundleSchema.describe("Self-contained SM definitions to execute"),
|
|
33605
|
-
params:
|
|
33606
|
-
|
|
33711
|
+
params: smRuntimeParamsSchema.describe(
|
|
33712
|
+
"Scenario parameter values (string or string[]; numeric/boolean params pass as strings)"
|
|
33713
|
+
),
|
|
33714
|
+
options: smRunInlineOptionsSchema.describe(
|
|
33715
|
+
"Tab / timeout / abort / dry-run / maxTotalIterations"
|
|
33716
|
+
)
|
|
33607
33717
|
})
|
|
33608
33718
|
};
|
|
33609
33719
|
var smProbeInlineTool = {
|
|
@@ -33616,12 +33726,19 @@ var smProbeInlineTool = {
|
|
|
33616
33726
|
inputSchema: external_exports.object({
|
|
33617
33727
|
bundle: smBundleSchema.describe("Bundle whose target locators to probe"),
|
|
33618
33728
|
targetIds: external_exports.array(external_exports.string()).optional().describe("Subset of target_ids to probe; default = all targets in the bundle"),
|
|
33729
|
+
// F3: probe also exercises scenario.params resolution so callers get a
|
|
33730
|
+
// `missing-params` / `invalid-param-value` signal before committing to
|
|
33731
|
+
// a full run. Probe itself runs no scenario steps.
|
|
33732
|
+
params: smRuntimeParamsSchema.describe(
|
|
33733
|
+
"Scenario parameter values for resolution-only validation (probe does not execute steps)"
|
|
33734
|
+
),
|
|
33619
33735
|
options: external_exports.object({
|
|
33620
33736
|
tabId: external_exports.coerce.number().optional(),
|
|
33621
33737
|
tabStrategy: external_exports.enum(["reuse", "create", "create-then-close"]).optional(),
|
|
33622
33738
|
chromeProfile: external_exports.string().optional(),
|
|
33623
33739
|
timeoutMs: external_exports.coerce.number().int().positive().optional(),
|
|
33624
|
-
abortSignal: external_exports.string().optional()
|
|
33740
|
+
abortSignal: external_exports.string().optional(),
|
|
33741
|
+
maxTotalIterations: external_exports.coerce.number().int().positive().optional()
|
|
33625
33742
|
}).optional()
|
|
33626
33743
|
})
|
|
33627
33744
|
};
|
|
@@ -34205,6 +34322,7 @@ function computeToolTimeout(tool, input) {
|
|
|
34205
34322
|
var pendingRequests = /* @__PURE__ */ new Map();
|
|
34206
34323
|
var bridgeClient = null;
|
|
34207
34324
|
var bridgeUpdateInfo = null;
|
|
34325
|
+
var shutdownGate = createShutdownGateState();
|
|
34208
34326
|
function getBridgeSocket() {
|
|
34209
34327
|
return bridgeClient?.getSocket() ?? null;
|
|
34210
34328
|
}
|
|
@@ -34325,7 +34443,7 @@ function coerceShape(shape) {
|
|
|
34325
34443
|
return result;
|
|
34326
34444
|
}
|
|
34327
34445
|
function handleFileExport(filePath, result) {
|
|
34328
|
-
|
|
34446
|
+
mkdirSync4(dirname2(filePath), { recursive: true });
|
|
34329
34447
|
let content;
|
|
34330
34448
|
let metadata;
|
|
34331
34449
|
if (typeof result.data === "string") {
|
|
@@ -34345,7 +34463,7 @@ function handleFileExport(filePath, result) {
|
|
|
34345
34463
|
const pages = Array.isArray(result.pages) ? result.pages : [];
|
|
34346
34464
|
metadata = { ok: true, file_path: filePath, page_count: pages.length };
|
|
34347
34465
|
}
|
|
34348
|
-
|
|
34466
|
+
writeFileSync3(filePath, content, "utf-8");
|
|
34349
34467
|
metadata.file_size = Buffer.byteLength(content, "utf-8");
|
|
34350
34468
|
return metadata;
|
|
34351
34469
|
}
|
|
@@ -34733,7 +34851,7 @@ async function handleStreamableHttpRequest(req, res, sessions2) {
|
|
|
34733
34851
|
}
|
|
34734
34852
|
var MAX_BODY_SIZE = 4 * 1024 * 1024;
|
|
34735
34853
|
function parseJsonBody(req) {
|
|
34736
|
-
return new Promise((
|
|
34854
|
+
return new Promise((resolve4, reject) => {
|
|
34737
34855
|
const chunks = [];
|
|
34738
34856
|
let size = 0;
|
|
34739
34857
|
let destroyed = false;
|
|
@@ -34751,7 +34869,7 @@ function parseJsonBody(req) {
|
|
|
34751
34869
|
req.on("end", () => {
|
|
34752
34870
|
if (destroyed) return;
|
|
34753
34871
|
try {
|
|
34754
|
-
|
|
34872
|
+
resolve4(JSON.parse(Buffer.concat(chunks).toString("utf-8")));
|
|
34755
34873
|
} catch (error2) {
|
|
34756
34874
|
reject(new Error(`Invalid JSON: ${error2.message}`));
|
|
34757
34875
|
}
|
|
@@ -34919,15 +35037,24 @@ function handleExtensionMessage(message2) {
|
|
|
34919
35037
|
const bridgeVersion = typeof msg.bridgeVersion === "string" ? msg.bridgeVersion : null;
|
|
34920
35038
|
if (bridgeVersion && shouldUpdateBridge(bridgeVersion)) {
|
|
34921
35039
|
const serverVersion = getPackageVersion();
|
|
34922
|
-
|
|
34923
|
-
|
|
35040
|
+
const nowMs = Date.now();
|
|
35041
|
+
if (shouldSendShutdownRequest(shutdownGate, bridgeVersion, nowMs)) {
|
|
35042
|
+
process.stderr.write(
|
|
35043
|
+
`[viyv-browser:mcp] Bridge version mismatch (bridge=${bridgeVersion}, server=${serverVersion}), requesting restart
|
|
34924
35044
|
`
|
|
34925
|
-
|
|
34926
|
-
|
|
34927
|
-
|
|
34928
|
-
|
|
34929
|
-
|
|
34930
|
-
|
|
35045
|
+
);
|
|
35046
|
+
bridgeUpdateInfo = { from: bridgeVersion, to: serverVersion };
|
|
35047
|
+
const shutdownSock = getBridgeSocket();
|
|
35048
|
+
if (shutdownSock) {
|
|
35049
|
+
shutdownSock.write(
|
|
35050
|
+
`${JSON.stringify({ type: "bridge_shutdown_request", timestamp: nowMs })}
|
|
35051
|
+
`
|
|
35052
|
+
);
|
|
35053
|
+
shutdownGate = markSent(shutdownGate, bridgeVersion, nowMs);
|
|
35054
|
+
}
|
|
35055
|
+
} else {
|
|
35056
|
+
process.stderr.write(
|
|
35057
|
+
`[viyv-browser:mcp] Skipping bridge_shutdown_request \u2014 same version ${bridgeVersion} within cooldown (orphan MCP or external tampering is re-seeding the deploy binary; check for stale viyv-browser-mcp processes)
|
|
34931
35058
|
`
|
|
34932
35059
|
);
|
|
34933
35060
|
}
|
|
@@ -35070,7 +35197,7 @@ async function callExtensionTool(tool, input) {
|
|
|
35070
35197
|
if (paths) {
|
|
35071
35198
|
for (const p of paths) {
|
|
35072
35199
|
try {
|
|
35073
|
-
if (!
|
|
35200
|
+
if (!existsSync3(p) || !statSync(p).isFile()) {
|
|
35074
35201
|
return {
|
|
35075
35202
|
content: [
|
|
35076
35203
|
{
|
|
@@ -35102,7 +35229,7 @@ async function callExtensionTool(tool, input) {
|
|
|
35102
35229
|
let csvData;
|
|
35103
35230
|
if (typeof input.file_path === "string") {
|
|
35104
35231
|
const fp = input.file_path;
|
|
35105
|
-
if (!
|
|
35232
|
+
if (!existsSync3(fp) || !statSync(fp).isFile()) {
|
|
35106
35233
|
return {
|
|
35107
35234
|
content: [
|
|
35108
35235
|
{
|
|
@@ -35114,7 +35241,7 @@ async function callExtensionTool(tool, input) {
|
|
|
35114
35241
|
]
|
|
35115
35242
|
};
|
|
35116
35243
|
}
|
|
35117
|
-
csvData =
|
|
35244
|
+
csvData = readFileSync5(fp, "utf-8");
|
|
35118
35245
|
} else if (typeof input.data === "string") {
|
|
35119
35246
|
csvData = input.data;
|
|
35120
35247
|
}
|
|
@@ -35160,13 +35287,13 @@ async function callExtensionTool(tool, input) {
|
|
|
35160
35287
|
touchSession(agentId);
|
|
35161
35288
|
const client = bridgeClient;
|
|
35162
35289
|
const toolTimeout = computeToolTimeout(tool, input);
|
|
35163
|
-
return new Promise((
|
|
35290
|
+
return new Promise((resolve4) => {
|
|
35164
35291
|
const removeErrorListener = () => {
|
|
35165
35292
|
};
|
|
35166
35293
|
const timer = setTimeout(() => {
|
|
35167
35294
|
pendingRequests.delete(requestId);
|
|
35168
35295
|
removeErrorListener();
|
|
35169
|
-
|
|
35296
|
+
resolve4({
|
|
35170
35297
|
content: [
|
|
35171
35298
|
{
|
|
35172
35299
|
type: "text",
|
|
@@ -35193,12 +35320,12 @@ async function callExtensionTool(tool, input) {
|
|
|
35193
35320
|
if (FILE_EXPORT_TOOLS.has(tool) && typeof filePath === "string" && ("data" in result || "pages" in result)) {
|
|
35194
35321
|
try {
|
|
35195
35322
|
const metadata = handleFileExport(filePath, result);
|
|
35196
|
-
|
|
35323
|
+
resolve4({
|
|
35197
35324
|
content: [{ type: "text", text: JSON.stringify(metadata) }]
|
|
35198
35325
|
});
|
|
35199
35326
|
} catch (e) {
|
|
35200
35327
|
const msg = e instanceof Error ? e.message : String(e);
|
|
35201
|
-
|
|
35328
|
+
resolve4({
|
|
35202
35329
|
content: [
|
|
35203
35330
|
{
|
|
35204
35331
|
type: "text",
|
|
@@ -35217,9 +35344,9 @@ async function callExtensionTool(tool, input) {
|
|
|
35217
35344
|
if (RESULT_EXPORT_TOOLS.has(tool) && typeof filePath === "string") {
|
|
35218
35345
|
try {
|
|
35219
35346
|
const content = JSON.stringify(result, null, 2);
|
|
35220
|
-
|
|
35221
|
-
|
|
35222
|
-
|
|
35347
|
+
mkdirSync4(dirname2(filePath), { recursive: true });
|
|
35348
|
+
writeFileSync3(filePath, content, "utf-8");
|
|
35349
|
+
resolve4({
|
|
35223
35350
|
content: [
|
|
35224
35351
|
{
|
|
35225
35352
|
type: "text",
|
|
@@ -35232,7 +35359,7 @@ async function callExtensionTool(tool, input) {
|
|
|
35232
35359
|
});
|
|
35233
35360
|
} catch (e) {
|
|
35234
35361
|
const msg = e instanceof Error ? e.message : String(e);
|
|
35235
|
-
|
|
35362
|
+
resolve4({
|
|
35236
35363
|
content: [
|
|
35237
35364
|
{
|
|
35238
35365
|
type: "text",
|
|
@@ -35259,21 +35386,21 @@ async function callExtensionTool(tool, input) {
|
|
|
35259
35386
|
}
|
|
35260
35387
|
if (tempImportFile) {
|
|
35261
35388
|
try {
|
|
35262
|
-
|
|
35389
|
+
unlinkSync3(tempImportFile);
|
|
35263
35390
|
} catch {
|
|
35264
35391
|
}
|
|
35265
35392
|
}
|
|
35266
|
-
|
|
35393
|
+
resolve4({ content: buildResponseContent(tool, finalResult) });
|
|
35267
35394
|
},
|
|
35268
35395
|
reject: (error2) => {
|
|
35269
35396
|
removeErrorListener();
|
|
35270
35397
|
if (tempImportFile) {
|
|
35271
35398
|
try {
|
|
35272
|
-
|
|
35399
|
+
unlinkSync3(tempImportFile);
|
|
35273
35400
|
} catch {
|
|
35274
35401
|
}
|
|
35275
35402
|
}
|
|
35276
|
-
|
|
35403
|
+
resolve4({
|
|
35277
35404
|
content: [
|
|
35278
35405
|
{
|
|
35279
35406
|
type: "text",
|
|
@@ -35314,7 +35441,7 @@ async function callExtensionTool(tool, input) {
|
|
|
35314
35441
|
clearTimeout(pending.timer);
|
|
35315
35442
|
pendingRequests.delete(requestId);
|
|
35316
35443
|
const { code, message: message2 } = toolCallRejectionToErrorCode(rej);
|
|
35317
|
-
|
|
35444
|
+
resolve4({
|
|
35318
35445
|
content: [{ type: "text", text: JSON.stringify({ error: { code, message: message2 } }) }]
|
|
35319
35446
|
});
|
|
35320
35447
|
});
|
|
@@ -35338,12 +35465,12 @@ async function handleSwitchBrowser() {
|
|
|
35338
35465
|
setExtensionConnected(false);
|
|
35339
35466
|
}
|
|
35340
35467
|
process.stderr.write("[viyv-browser:mcp] switch_browser: waiting for bridge reconnection...\n");
|
|
35341
|
-
return new Promise((
|
|
35468
|
+
return new Promise((resolve4) => {
|
|
35342
35469
|
const checkInterval = setInterval(() => {
|
|
35343
35470
|
if (bridgeClient?.isReady() && isExtensionConnected()) {
|
|
35344
35471
|
clearInterval(checkInterval);
|
|
35345
35472
|
clearTimeout(timer);
|
|
35346
|
-
|
|
35473
|
+
resolve4({
|
|
35347
35474
|
content: [
|
|
35348
35475
|
{
|
|
35349
35476
|
type: "text",
|
|
@@ -35358,7 +35485,7 @@ async function handleSwitchBrowser() {
|
|
|
35358
35485
|
}, 500);
|
|
35359
35486
|
const timer = setTimeout(() => {
|
|
35360
35487
|
clearInterval(checkInterval);
|
|
35361
|
-
|
|
35488
|
+
resolve4({
|
|
35362
35489
|
content: [
|
|
35363
35490
|
{
|
|
35364
35491
|
type: "text",
|
|
@@ -35377,9 +35504,9 @@ async function handleSwitchBrowser() {
|
|
|
35377
35504
|
|
|
35378
35505
|
// src/setup.ts
|
|
35379
35506
|
import { execSync } from "child_process";
|
|
35380
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
35507
|
+
import { chmodSync as chmodSync3, existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
35381
35508
|
import { homedir as homedir2, platform } from "os";
|
|
35382
|
-
import { dirname as dirname3, resolve as
|
|
35509
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
35383
35510
|
function runSetup(options = {}) {
|
|
35384
35511
|
const os = platform();
|
|
35385
35512
|
console.log("Viyv Browser MCP - Native Messaging Host Setup");
|
|
@@ -35411,8 +35538,8 @@ function runSetup(options = {}) {
|
|
|
35411
35538
|
console.log(`Wrapper: ${wrapperPath}`);
|
|
35412
35539
|
for (const manifestPath of manifestPaths) {
|
|
35413
35540
|
console.log(`Manifest path: ${manifestPath}`);
|
|
35414
|
-
|
|
35415
|
-
|
|
35541
|
+
mkdirSync5(dirname3(manifestPath), { recursive: true });
|
|
35542
|
+
writeFileSync4(manifestPath, JSON.stringify(manifest, null, 2));
|
|
35416
35543
|
chmodSync3(manifestPath, 420);
|
|
35417
35544
|
}
|
|
35418
35545
|
console.log("\nNative Messaging Host registered successfully!");
|
|
@@ -35426,17 +35553,17 @@ function runSetup(options = {}) {
|
|
|
35426
35553
|
}
|
|
35427
35554
|
function createNativeHostWrapper(os, binaryPath, dockerMode) {
|
|
35428
35555
|
const manifestDir = dockerMode ? "/etc/chromium/native-messaging-hosts" : dirname3(getManifestPath(os));
|
|
35429
|
-
|
|
35556
|
+
mkdirSync5(manifestDir, { recursive: true });
|
|
35430
35557
|
const nodePath = getNodePath();
|
|
35431
35558
|
if (os === "win32") {
|
|
35432
|
-
const wrapperPath2 =
|
|
35433
|
-
|
|
35559
|
+
const wrapperPath2 = resolve3(manifestDir, `${NATIVE_HOST_NAME}.bat`);
|
|
35560
|
+
writeFileSync4(wrapperPath2, `@echo off\r
|
|
35434
35561
|
"${nodePath}" "${binaryPath}" --native-host\r
|
|
35435
35562
|
`);
|
|
35436
35563
|
return wrapperPath2;
|
|
35437
35564
|
}
|
|
35438
|
-
const wrapperPath =
|
|
35439
|
-
|
|
35565
|
+
const wrapperPath = resolve3(manifestDir, `${NATIVE_HOST_NAME}.sh`);
|
|
35566
|
+
writeFileSync4(wrapperPath, `#!/bin/bash
|
|
35440
35567
|
exec "${nodePath}" "${binaryPath}" --native-host
|
|
35441
35568
|
`);
|
|
35442
35569
|
chmodSync3(wrapperPath, 493);
|
|
@@ -35451,23 +35578,23 @@ function getNodePath() {
|
|
|
35451
35578
|
}
|
|
35452
35579
|
function getDockerManifestPaths() {
|
|
35453
35580
|
return [
|
|
35454
|
-
|
|
35455
|
-
|
|
35581
|
+
resolve3("/etc/chromium/native-messaging-hosts", `${NATIVE_HOST_NAME}.json`),
|
|
35582
|
+
resolve3(homedir2(), ".config/chromium/NativeMessagingHosts", `${NATIVE_HOST_NAME}.json`)
|
|
35456
35583
|
];
|
|
35457
35584
|
}
|
|
35458
35585
|
function getManifestPath(os) {
|
|
35459
35586
|
const home = homedir2();
|
|
35460
35587
|
switch (os) {
|
|
35461
35588
|
case "darwin":
|
|
35462
|
-
return
|
|
35589
|
+
return resolve3(
|
|
35463
35590
|
home,
|
|
35464
35591
|
"Library/Application Support/Google/Chrome/NativeMessagingHosts",
|
|
35465
35592
|
`${NATIVE_HOST_NAME}.json`
|
|
35466
35593
|
);
|
|
35467
35594
|
case "linux":
|
|
35468
|
-
return
|
|
35595
|
+
return resolve3(home, ".config/google-chrome/NativeMessagingHosts", `${NATIVE_HOST_NAME}.json`);
|
|
35469
35596
|
case "win32":
|
|
35470
|
-
return
|
|
35597
|
+
return resolve3(
|
|
35471
35598
|
home,
|
|
35472
35599
|
"AppData/Local/Google/Chrome/User Data/NativeMessagingHosts",
|
|
35473
35600
|
`${NATIVE_HOST_NAME}.json`
|
|
@@ -35487,9 +35614,9 @@ function setupClaudeDesktopConfig() {
|
|
|
35487
35614
|
const configPath = getClaudeDesktopConfigPath();
|
|
35488
35615
|
console.log(`Config path: ${configPath}`);
|
|
35489
35616
|
let config2 = {};
|
|
35490
|
-
if (
|
|
35617
|
+
if (existsSync4(configPath)) {
|
|
35491
35618
|
try {
|
|
35492
|
-
config2 = JSON.parse(
|
|
35619
|
+
config2 = JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
35493
35620
|
} catch {
|
|
35494
35621
|
console.error(
|
|
35495
35622
|
`ERROR: Failed to parse ${configPath}. Fix the JSON manually or delete the file.`
|
|
@@ -35509,8 +35636,8 @@ function setupClaudeDesktopConfig() {
|
|
|
35509
35636
|
env: { PATH: envPath }
|
|
35510
35637
|
};
|
|
35511
35638
|
const configDir = dirname3(configPath);
|
|
35512
|
-
|
|
35513
|
-
|
|
35639
|
+
mkdirSync5(configDir, { recursive: true });
|
|
35640
|
+
writeFileSync4(configPath, JSON.stringify(config2, null, 2));
|
|
35514
35641
|
console.log(`npx path: ${npxPath}`);
|
|
35515
35642
|
console.log("\nClaude Desktop config updated successfully!");
|
|
35516
35643
|
console.log("Please restart Claude Desktop for changes to take effect.");
|
|
@@ -35527,13 +35654,13 @@ function getClaudeDesktopConfigPath() {
|
|
|
35527
35654
|
const home = homedir2();
|
|
35528
35655
|
switch (process.platform) {
|
|
35529
35656
|
case "darwin":
|
|
35530
|
-
return
|
|
35657
|
+
return resolve3(home, "Library/Application Support/Claude/claude_desktop_config.json");
|
|
35531
35658
|
case "linux":
|
|
35532
|
-
return
|
|
35659
|
+
return resolve3(home, ".config/Claude/claude_desktop_config.json");
|
|
35533
35660
|
case "win32":
|
|
35534
|
-
return
|
|
35661
|
+
return resolve3(home, "AppData/Roaming/Claude/claude_desktop_config.json");
|
|
35535
35662
|
default:
|
|
35536
|
-
return
|
|
35663
|
+
return resolve3(home, ".config/Claude/claude_desktop_config.json");
|
|
35537
35664
|
}
|
|
35538
35665
|
}
|
|
35539
35666
|
|
|
@@ -35575,7 +35702,18 @@ if (args.includes("setup")) {
|
|
|
35575
35702
|
const authBearer = authIdx >= 0 ? args[authIdx + 1] : process.env.VIYV_MCP_AUTH_BEARER;
|
|
35576
35703
|
if (isNativeHostDeployed()) {
|
|
35577
35704
|
try {
|
|
35578
|
-
|
|
35705
|
+
const decision = syncNativeHostBinaryIfNeeded();
|
|
35706
|
+
if (decision.shouldSync) {
|
|
35707
|
+
process.stderr.write(
|
|
35708
|
+
`[viyv-browser:mcp] Native host binary synced (self=${decision.selfVersion}, was=${decision.deployedVersion ?? "unknown"}, reason=${decision.reason})
|
|
35709
|
+
`
|
|
35710
|
+
);
|
|
35711
|
+
} else {
|
|
35712
|
+
process.stderr.write(
|
|
35713
|
+
`[viyv-browser:mcp] Native host sync skipped \u2014 deployed v${decision.deployedVersion} is newer than self v${decision.selfVersion} (preventing downgrade by orphan MCP)
|
|
35714
|
+
`
|
|
35715
|
+
);
|
|
35716
|
+
}
|
|
35579
35717
|
} catch (err) {
|
|
35580
35718
|
process.stderr.write(
|
|
35581
35719
|
`[viyv-browser:mcp] WARNING: Failed to update native host binary: ${err.message}
|