cloakbrowser-mcp 1.3.0 → 1.5.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/README.md +101 -19
- package/dist/bridge/config.d.ts +26 -3
- package/dist/bridge/config.d.ts.map +1 -1
- package/dist/bridge/config.js +187 -13
- package/dist/bridge/config.js.map +1 -1
- package/dist/bridge/env.d.ts +1 -0
- package/dist/bridge/env.d.ts.map +1 -1
- package/dist/bridge/env.js +3 -0
- package/dist/bridge/env.js.map +1 -1
- package/dist/bridge/tools.d.ts +3 -1
- package/dist/bridge/tools.d.ts.map +1 -1
- package/dist/bridge/tools.js +8 -6
- package/dist/bridge/tools.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +3 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/options.d.ts +11 -2
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +115 -3
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/singleton-lock-cleanup.d.ts +34 -0
- package/dist/cli/singleton-lock-cleanup.d.ts.map +1 -0
- package/dist/cli/singleton-lock-cleanup.js +151 -0
- package/dist/cli/singleton-lock-cleanup.js.map +1 -0
- package/dist/cli.js +27 -10
- package/dist/cli.js.map +1 -1
- package/dist/http/nodeServer.d.ts +9 -0
- package/dist/http/nodeServer.d.ts.map +1 -0
- package/dist/http/nodeServer.js +65 -0
- package/dist/http/nodeServer.js.map +1 -0
- package/dist/http/options.d.ts +27 -2
- package/dist/http/options.d.ts.map +1 -1
- package/dist/http/options.js +25 -5
- package/dist/http/options.js.map +1 -1
- package/dist/http/requests.d.ts +16 -0
- package/dist/http/requests.d.ts.map +1 -0
- package/dist/http/requests.js +127 -0
- package/dist/http/requests.js.map +1 -0
- package/dist/http/responses.d.ts +6 -0
- package/dist/http/responses.d.ts.map +1 -0
- package/dist/http/responses.js +24 -0
- package/dist/http/responses.js.map +1 -0
- package/dist/http/server.d.ts +7 -3
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +61 -117
- package/dist/http/server.js.map +1 -1
- package/dist/http/sessionStore.d.ts +3 -1
- package/dist/http/sessionStore.d.ts.map +1 -1
- package/dist/http/sessionStore.js +8 -5
- package/dist/http/sessionStore.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/logging/logger.d.ts +17 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +107 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/protocol/constants.d.ts +6 -0
- package/dist/protocol/constants.d.ts.map +1 -0
- package/dist/protocol/constants.js +6 -0
- package/dist/protocol/constants.js.map +1 -0
- package/dist/runtime/humanize-init-page.cjs +19 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5 -5
- package/dist/server.js.map +1 -1
- package/package.json +39 -18
- package/server.json +29 -5
package/dist/bridge/tools.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { getCurrentCloakBinaryInfo } from '
|
|
2
|
-
import { CLOAKBROWSER_TOOL_COUNT, PLAYWRIGHT_MCP_BROWSER_TOOL_COUNT, PLAYWRIGHT_MCP_PACKAGE, PLAYWRIGHT_MCP_VERSION, PROJECT_METADATA, } from '
|
|
3
|
-
export const
|
|
1
|
+
import { getCurrentCloakBinaryInfo } from '#src/bridge/config';
|
|
2
|
+
import { CLOAKBROWSER_TOOL_COUNT, PLAYWRIGHT_MCP_BROWSER_TOOL_COUNT, PLAYWRIGHT_MCP_PACKAGE, PLAYWRIGHT_MCP_VERSION, PROJECT_METADATA, } from '#src/project/metadata';
|
|
3
|
+
export const LOCAL_TOOL_BINARY_INFO = 'cloakbrowser_binary_info';
|
|
4
|
+
export const LOCAL_TOOL_BRIDGE_INFO = 'cloakbrowser_bridge_info';
|
|
5
|
+
export const localToolNames = [LOCAL_TOOL_BINARY_INFO, LOCAL_TOOL_BRIDGE_INFO];
|
|
4
6
|
const localToolNameSet = new Set(localToolNames);
|
|
5
7
|
const emptyInputSchema = {
|
|
6
8
|
type: 'object',
|
|
@@ -9,7 +11,7 @@ const emptyInputSchema = {
|
|
|
9
11
|
};
|
|
10
12
|
const localTools = [
|
|
11
13
|
{
|
|
12
|
-
name:
|
|
14
|
+
name: LOCAL_TOOL_BINARY_INFO,
|
|
13
15
|
title: 'CloakBrowser binary info',
|
|
14
16
|
description: 'Return CloakBrowser package, cache, platform, and resolved browser binary information.',
|
|
15
17
|
inputSchema: emptyInputSchema,
|
|
@@ -20,7 +22,7 @@ const localTools = [
|
|
|
20
22
|
},
|
|
21
23
|
},
|
|
22
24
|
{
|
|
23
|
-
name:
|
|
25
|
+
name: LOCAL_TOOL_BRIDGE_INFO,
|
|
24
26
|
title: 'CloakBrowser bridge info',
|
|
25
27
|
description: 'Return runtime metadata for the CloakBrowser bridge over upstream Playwright MCP.',
|
|
26
28
|
inputSchema: emptyInputSchema,
|
|
@@ -38,7 +40,7 @@ export function isLocalTool(name) {
|
|
|
38
40
|
return localToolNameSet.has(name);
|
|
39
41
|
}
|
|
40
42
|
export function callLocalTool(name, runtime, upstreamToolCount) {
|
|
41
|
-
if (name ===
|
|
43
|
+
if (name === LOCAL_TOOL_BINARY_INFO) {
|
|
42
44
|
return jsonResult({
|
|
43
45
|
browserEngine: runtime.browserEngine,
|
|
44
46
|
executablePath: runtime.cloakBinaryPath ?? null,
|
package/dist/bridge/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/bridge/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAsB,MAAM,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/bridge/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAsB,MAAM,oBAAoB,CAAC;AACnF,OAAO,EACL,uBAAuB,EACvB,iCAAiC,EACjC,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAAmC,CAAC;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAAmC,CAAC;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,sBAAsB,EAAE,sBAAsB,CAAU,CAAC;AACxF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,cAAc,CAAC,CAAC;AAIzD,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,EAAE;IACd,oBAAoB,EAAE,KAAK;CACnB,CAAC;AAEX,MAAM,UAAU,GAAW;IACzB;QACE,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,wFAAwF;QACrG,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,mFAAmF;QAChG,WAAW,EAAE,gBAAgB;QAC7B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC9B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,IAAmB,EACnB,OAAsB,EACtB,iBAAyB;IAEzB,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;QACpC,OAAO,UAAU,CAAC;YAChB,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,cAAc,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI;YAC/C,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,yBAAyB,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,gBAAgB,CAAC,OAAO;QAC9B,KAAK,EAAE,gBAAgB,CAAC,KAAK;QAC7B,OAAO,EAAE,gBAAgB,CAAC,OAAO;QACjC,OAAO,EAAE,uBAAuB;QAChC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,QAAQ,EAAE;YACR,OAAO,EAAE,sBAAsB;YAC/B,OAAO,EAAE,sBAAsB;YAC/B,SAAS,EAAE,iBAAiB,IAAI,iCAAiC;SAClE;QACD,UAAU,EAAE;YACV,SAAS,EAAE,uBAAuB;YAClC,KAAK,EAAE,cAAc;SACtB;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,KAA8B;IAChD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACjE,iBAAiB,EAAE,KAAK;KACzB,CAAC;AACJ,CAAC"}
|
package/dist/cli/doctor.d.ts
CHANGED
package/dist/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAI/D,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;IACF,YAAY,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,GAAG,IAAI,CAAC;IAClE,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AA6BD,wBAAgB,kBAAkB,IAAI,YAAY,CAoFjD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAU/D"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import process from 'node:process';
|
|
3
|
-
import { getCurrentCloakBinaryInfo } from '
|
|
4
|
-
import { resolvePlaywrightMcpCliPath } from '
|
|
5
|
-
import { PLAYWRIGHT_MCP_PACKAGE, PLAYWRIGHT_MCP_VERSION, PROJECT_METADATA } from '
|
|
3
|
+
import { getCurrentCloakBinaryInfo } from '#src/bridge/config';
|
|
4
|
+
import { resolvePlaywrightMcpCliPath } from '#src/bridge/paths';
|
|
5
|
+
import { PLAYWRIGHT_MCP_PACKAGE, PLAYWRIGHT_MCP_VERSION, PROJECT_METADATA } from '#src/project/metadata';
|
|
6
6
|
const packageMetadata = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8'));
|
|
7
7
|
const doctorReportTemplate = `CloakBrowser MCP doctor
|
|
8
8
|
Status: {{status}}
|
package/dist/cli/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/options.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { type
|
|
2
|
+
import { type HumanPreset } from '#src/bridge/config';
|
|
3
|
+
import { type BridgeTransportMode, type CliOptions, type HttpProtocol, type HttpSessionBackend } from '#src/http/options';
|
|
3
4
|
export declare const cliDescription = "Playwright MCP bridge backed by CloakBrowser.";
|
|
4
5
|
interface CommanderCliOptions {
|
|
5
6
|
transport: BridgeTransportMode;
|
|
7
|
+
geoipProxyMatch: boolean;
|
|
8
|
+
humanize: boolean;
|
|
9
|
+
humanPreset: HumanPreset;
|
|
10
|
+
httpProtocol: HttpProtocol;
|
|
6
11
|
httpHost: string;
|
|
7
12
|
httpPort: number;
|
|
8
13
|
httpEndpoint: string;
|
|
9
14
|
httpAuthToken?: string;
|
|
15
|
+
httpsCert?: string;
|
|
16
|
+
httpsKey?: string;
|
|
17
|
+
httpsPfx?: string;
|
|
18
|
+
httpsPassphrase?: string;
|
|
10
19
|
httpSessionBackend: HttpSessionBackend;
|
|
11
20
|
httpSessionIdleTtlMs: number;
|
|
12
21
|
httpSessionMax: number;
|
|
@@ -17,7 +26,7 @@ interface DoctorCliOptions {
|
|
|
17
26
|
interface CreateCliCommandOptions {
|
|
18
27
|
doctorAction?: (options: DoctorCliOptions) => Promise<void> | void;
|
|
19
28
|
}
|
|
20
|
-
type CliOptionValue = string | number;
|
|
29
|
+
type CliOptionValue = string | number | boolean;
|
|
21
30
|
interface CliOptionDefinition {
|
|
22
31
|
name: keyof CommanderCliOptions;
|
|
23
32
|
flags: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgC,MAAM,WAAW,CAAC;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgC,MAAM,WAAW,CAAC;AAClE,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAUL,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,cAAc,kDAAkD,CAAC;AAE9E,UAAU,mBAAmB;IAC3B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACpE;AAED,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,mBAAmB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,cAAc,CAAC;CAC5C;AAED,eAAO,MAAM,oBAAoB,EAAE,SAAS,mBAAmB,EA0I9D,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAiBhG;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CASnE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAE3D;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBlE"}
|
package/dist/cli/options.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command, InvalidArgumentError, Option } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { humanPresets } from '#src/bridge/config';
|
|
3
|
+
import { BRIDGE_TRANSPORT_STDIO, HEALTHZ_PATH, HTTP_PROTOCOL_HTTP, READYZ_PATH, bridgeTransportModes, defaultStreamableHttpOptions, defaultBridgeOptions, httpProtocols, httpSessionBackends, } from '#src/http/options';
|
|
3
4
|
export const cliDescription = 'Playwright MCP bridge backed by CloakBrowser.';
|
|
4
5
|
export const cliOptionDefinitions = [
|
|
5
6
|
{
|
|
@@ -8,9 +9,43 @@ export const cliOptionDefinitions = [
|
|
|
8
9
|
description: 'MCP transport exposed by the bridge.',
|
|
9
10
|
env: 'CLOAK_PLAYWRIGHT_MCP_TRANSPORT',
|
|
10
11
|
group: 'Transport',
|
|
11
|
-
defaultValue:
|
|
12
|
+
defaultValue: BRIDGE_TRANSPORT_STDIO,
|
|
12
13
|
choices: bridgeTransportModes,
|
|
13
14
|
},
|
|
15
|
+
{
|
|
16
|
+
name: 'geoipProxyMatch',
|
|
17
|
+
flags: '--geoip-proxy-match',
|
|
18
|
+
description: 'Match CloakBrowser timezone and locale to the configured proxy GeoIP.',
|
|
19
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_GEOIP_PROXY_MATCH',
|
|
20
|
+
group: 'Bridge',
|
|
21
|
+
defaultValue: defaultBridgeOptions.geoipProxyMatch,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'humanize',
|
|
25
|
+
flags: '--humanize',
|
|
26
|
+
description: 'Enable CloakBrowser human-like mouse, keyboard, and scroll behavior.',
|
|
27
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HUMANIZE',
|
|
28
|
+
group: 'Bridge',
|
|
29
|
+
defaultValue: defaultBridgeOptions.humanize,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'humanPreset',
|
|
33
|
+
flags: '--human-preset <preset>',
|
|
34
|
+
description: 'CloakBrowser human behavior preset. Used only when humanize is enabled.',
|
|
35
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HUMAN_PRESET',
|
|
36
|
+
group: 'Bridge',
|
|
37
|
+
defaultValue: defaultBridgeOptions.humanPreset,
|
|
38
|
+
choices: humanPresets,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'httpProtocol',
|
|
42
|
+
flags: '--http-protocol <protocol>',
|
|
43
|
+
description: 'Streamable HTTP listener protocol.',
|
|
44
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HTTP_PROTOCOL',
|
|
45
|
+
group: 'Streamable HTTP',
|
|
46
|
+
defaultValue: defaultStreamableHttpOptions.protocol,
|
|
47
|
+
choices: httpProtocols,
|
|
48
|
+
},
|
|
14
49
|
{
|
|
15
50
|
name: 'httpHost',
|
|
16
51
|
flags: '--http-host <host>',
|
|
@@ -46,6 +81,38 @@ export const cliOptionDefinitions = [
|
|
|
46
81
|
group: 'Streamable HTTP',
|
|
47
82
|
parser: parseNonEmptyString('HTTP auth token must not be empty'),
|
|
48
83
|
},
|
|
84
|
+
{
|
|
85
|
+
name: 'httpsCert',
|
|
86
|
+
flags: '--https-cert <path>',
|
|
87
|
+
description: 'TLS certificate PEM file for HTTPS Streamable HTTP.',
|
|
88
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HTTPS_CERT',
|
|
89
|
+
group: 'Streamable HTTP',
|
|
90
|
+
parser: parseNonEmptyString('HTTPS certificate path must not be empty'),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'httpsKey',
|
|
94
|
+
flags: '--https-key <path>',
|
|
95
|
+
description: 'TLS private key PEM file for HTTPS Streamable HTTP.',
|
|
96
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HTTPS_KEY',
|
|
97
|
+
group: 'Streamable HTTP',
|
|
98
|
+
parser: parseNonEmptyString('HTTPS private key path must not be empty'),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'httpsPfx',
|
|
102
|
+
flags: '--https-pfx <path>',
|
|
103
|
+
description: 'TLS PFX/PKCS12 file for HTTPS Streamable HTTP.',
|
|
104
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HTTPS_PFX',
|
|
105
|
+
group: 'Streamable HTTP',
|
|
106
|
+
parser: parseNonEmptyString('HTTPS PFX path must not be empty'),
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'httpsPassphrase',
|
|
110
|
+
flags: '--https-passphrase <value>',
|
|
111
|
+
description: 'Passphrase for an encrypted HTTPS key or PFX.',
|
|
112
|
+
env: 'CLOAK_PLAYWRIGHT_MCP_HTTPS_PASSPHRASE',
|
|
113
|
+
group: 'Streamable HTTP',
|
|
114
|
+
parser: parseNonEmptyString('HTTPS passphrase must not be empty'),
|
|
115
|
+
},
|
|
49
116
|
{
|
|
50
117
|
name: 'httpSessionBackend',
|
|
51
118
|
flags: '--http-session-backend <backend>',
|
|
@@ -155,13 +222,22 @@ function createCommanderOption(definition) {
|
|
|
155
222
|
return option;
|
|
156
223
|
}
|
|
157
224
|
function toCliOptions(options) {
|
|
225
|
+
const tls = normalizeTlsOptions(options);
|
|
226
|
+
validateHttpProtocolOptions(options.httpProtocol, tls);
|
|
158
227
|
return {
|
|
159
228
|
transport: options.transport,
|
|
229
|
+
bridge: {
|
|
230
|
+
geoipProxyMatch: normalizeBoolean(options.geoipProxyMatch),
|
|
231
|
+
humanize: normalizeBoolean(options.humanize),
|
|
232
|
+
humanPreset: options.humanPreset,
|
|
233
|
+
},
|
|
160
234
|
http: {
|
|
235
|
+
protocol: options.httpProtocol,
|
|
161
236
|
host: options.httpHost,
|
|
162
237
|
port: options.httpPort,
|
|
163
238
|
endpoint: options.httpEndpoint,
|
|
164
239
|
authToken: optionalString(options.httpAuthToken),
|
|
240
|
+
tls,
|
|
165
241
|
sessionBackend: options.httpSessionBackend,
|
|
166
242
|
sessionIdleTtlMs: options.httpSessionIdleTtlMs,
|
|
167
243
|
sessionMax: options.httpSessionMax,
|
|
@@ -169,6 +245,42 @@ function toCliOptions(options) {
|
|
|
169
245
|
},
|
|
170
246
|
};
|
|
171
247
|
}
|
|
248
|
+
function normalizeBoolean(value) {
|
|
249
|
+
if (typeof value === 'boolean')
|
|
250
|
+
return value;
|
|
251
|
+
if (value === undefined)
|
|
252
|
+
return false;
|
|
253
|
+
return ['1', 'true', 'yes', 'on'].includes(value.toLowerCase());
|
|
254
|
+
}
|
|
255
|
+
function normalizeTlsOptions(options) {
|
|
256
|
+
return {
|
|
257
|
+
cert: optionalString(options.httpsCert),
|
|
258
|
+
key: optionalString(options.httpsKey),
|
|
259
|
+
pfx: optionalString(options.httpsPfx),
|
|
260
|
+
passphrase: optionalString(options.httpsPassphrase),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function validateHttpProtocolOptions(protocol, tls) {
|
|
264
|
+
const hasCert = tls.cert !== undefined;
|
|
265
|
+
const hasKey = tls.key !== undefined;
|
|
266
|
+
const hasPfx = tls.pfx !== undefined;
|
|
267
|
+
const hasPassphrase = tls.passphrase !== undefined;
|
|
268
|
+
const hasAnyTlsOption = hasCert || hasKey || hasPfx || hasPassphrase;
|
|
269
|
+
if (protocol === HTTP_PROTOCOL_HTTP) {
|
|
270
|
+
if (hasAnyTlsOption) {
|
|
271
|
+
throw new InvalidArgumentError('HTTPS certificate options require --http-protocol https');
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (hasPfx && (hasCert || hasKey)) {
|
|
276
|
+
throw new InvalidArgumentError('HTTPS must use either --https-pfx or --https-cert with --https-key');
|
|
277
|
+
}
|
|
278
|
+
if (hasPfx)
|
|
279
|
+
return;
|
|
280
|
+
if (hasCert && hasKey)
|
|
281
|
+
return;
|
|
282
|
+
throw new InvalidArgumentError('HTTPS requires either --https-cert and --https-key, or --https-pfx');
|
|
283
|
+
}
|
|
172
284
|
function renderCliReferenceFrontMatter() {
|
|
173
285
|
return `---
|
|
174
286
|
description: Generated CLI reference for cloakbrowser-mcp.
|
|
@@ -228,7 +340,7 @@ function parseHttpEndpoint(value) {
|
|
|
228
340
|
if (!value.startsWith('/') || value.includes('?') || value.includes('#')) {
|
|
229
341
|
throw new InvalidArgumentError('HTTP endpoint must be an absolute path such as "/mcp"');
|
|
230
342
|
}
|
|
231
|
-
if (value ===
|
|
343
|
+
if (value === HEALTHZ_PATH || value === READYZ_PATH) {
|
|
232
344
|
throw new InvalidArgumentError('HTTP endpoint must not use reserved probe paths "/healthz" or "/readyz"');
|
|
233
345
|
}
|
|
234
346
|
if (value.length > 1 && value.endsWith('/')) {
|
package/dist/cli/options.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the platform-specific Playwright MCP cache directory.
|
|
3
|
+
* Exported for testability — the win32 branch uses env vars that
|
|
4
|
+
* cannot be exercised cleanly on POSIX CI hosts.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getCacheDir(platform: NodeJS.Platform): string;
|
|
7
|
+
/**
|
|
8
|
+
* Reads the owning PID from a `SingletonLock` entry, handling both POSIX
|
|
9
|
+
* symlink targets and Windows plain-file content. Returns `null` when the
|
|
10
|
+
* lock is missing, unreadable, or has no valid positive PID.
|
|
11
|
+
* Exported for testability.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readLockPid(lockPath: string, platform: NodeJS.Platform): number | null;
|
|
14
|
+
/** Options accepted by {@link cleanStaleSingletonLocks}. */
|
|
15
|
+
export interface CleanStaleSingletonLocksOptions {
|
|
16
|
+
/** Override the cache directory (used by tests). */
|
|
17
|
+
readonly cacheDir?: string;
|
|
18
|
+
/** Override the platform identifier (used by tests). */
|
|
19
|
+
readonly platform?: NodeJS.Platform;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Iterates every `mcp-chromium-*` profile directory under the platform cache
|
|
23
|
+
* directory and removes the `SingletonLock` / `SingletonCookie` /
|
|
24
|
+
* `SingletonSocket` files whose owning PID is no longer alive.
|
|
25
|
+
*
|
|
26
|
+
* Safety guarantees:
|
|
27
|
+
* - Skips the cache directory silently if it does not exist.
|
|
28
|
+
* - Skips entries whose lock file is missing or unreadable.
|
|
29
|
+
* - Skips entries whose owning PID is still alive.
|
|
30
|
+
* - Skips entries whose PID status is indeterminate (EPERM, etc.).
|
|
31
|
+
* - Skips entries with malformed PID values (negative, zero, non-integer).
|
|
32
|
+
*/
|
|
33
|
+
export declare function cleanStaleSingletonLocks(options?: CleanStaleSingletonLocksOptions): void;
|
|
34
|
+
//# sourceMappingURL=singleton-lock-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton-lock-cleanup.d.ts","sourceRoot":"","sources":["../../src/cli/singleton-lock-cleanup.ts"],"names":[],"mappings":"AAmCA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAiB7D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,GAAG,IAAI,CAuBtF;AAwBD,4DAA4D;AAC5D,MAAM,WAAW,+BAA+B;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,+BAAoC,GAAG,IAAI,CAyB5F"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean stale Chromium `SingletonLock` files left behind by killed browser
|
|
3
|
+
* processes. Chromium uses these locks to prevent concurrent profile access —
|
|
4
|
+
* when the browser is killed with SIGKILL or crashes, the lock files remain
|
|
5
|
+
* and block every subsequent launch with "Browser is already in use".
|
|
6
|
+
*
|
|
7
|
+
* Runs on every CloakBrowser MCP stdio startup, before the Playwright MCP
|
|
8
|
+
* subprocess is spawned, so the downstream process never sees a zombie lock.
|
|
9
|
+
*
|
|
10
|
+
* Lock format differs by platform:
|
|
11
|
+
* - POSIX (Linux, macOS): `SingletonLock` is a symlink whose target ends in
|
|
12
|
+
* the owning PID, e.g. `profile-12345` -> `hostname-12345`.
|
|
13
|
+
* - Windows: `SingletonLock` is a regular file whose first line is the
|
|
14
|
+
* owning PID, e.g. `12345\nhostname\n`.
|
|
15
|
+
*
|
|
16
|
+
* Safety: never deletes a lock whose owning PID is still alive, whose
|
|
17
|
+
* status cannot be confirmed (e.g. EPERM), or whose PID value is missing,
|
|
18
|
+
* non-positive, or not a safe integer.
|
|
19
|
+
*
|
|
20
|
+
* Related upstream issues (fixed in newer @playwright/mcp but not in the
|
|
21
|
+
* version that ships with CloakBrowser):
|
|
22
|
+
* - microsoft/playwright-mcp#1311
|
|
23
|
+
* - microsoft/playwright-mcp#1305
|
|
24
|
+
* - microsoft/playwright-mcp#1245
|
|
25
|
+
*/
|
|
26
|
+
import { existsSync, readFileSync, readdirSync, readlinkSync, unlinkSync } from 'node:fs';
|
|
27
|
+
import { homedir } from 'node:os';
|
|
28
|
+
import { join as joinPosix } from 'node:path/posix';
|
|
29
|
+
import { join as joinWin32 } from 'node:path/win32';
|
|
30
|
+
const SINGLETON_LOCK_FILES = ['SingletonLock', 'SingletonCookie', 'SingletonSocket'];
|
|
31
|
+
const PROFILE_DIR_PREFIX = 'mcp-chromium-';
|
|
32
|
+
const CACHE_DIR_NAME = 'ms-playwright-mcp';
|
|
33
|
+
const PID_REGEX = /\d+$/;
|
|
34
|
+
/**
|
|
35
|
+
* Resolves the platform-specific Playwright MCP cache directory.
|
|
36
|
+
* Exported for testability — the win32 branch uses env vars that
|
|
37
|
+
* cannot be exercised cleanly on POSIX CI hosts.
|
|
38
|
+
*/
|
|
39
|
+
export function getCacheDir(platform) {
|
|
40
|
+
if (platform === 'win32') {
|
|
41
|
+
// `%LOCALAPPDATA%` is the Windows default; fall back to `%USERPROFILE%`
|
|
42
|
+
// for unusual shells, and finally to `homedir()`.
|
|
43
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
44
|
+
const userProfile = process.env.USERPROFILE;
|
|
45
|
+
const base = localAppData && localAppData.length > 0
|
|
46
|
+
? localAppData
|
|
47
|
+
: userProfile && userProfile.length > 0
|
|
48
|
+
? userProfile
|
|
49
|
+
: homedir();
|
|
50
|
+
// `path.win32.join` keeps `\` separators even on POSIX CI hosts so the
|
|
51
|
+
// path matches what the Windows Chromium process will resolve later.
|
|
52
|
+
return joinWin32(base, CACHE_DIR_NAME);
|
|
53
|
+
}
|
|
54
|
+
return joinPosix(homedir(), '.cache', CACHE_DIR_NAME);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reads the owning PID from a `SingletonLock` entry, handling both POSIX
|
|
58
|
+
* symlink targets and Windows plain-file content. Returns `null` when the
|
|
59
|
+
* lock is missing, unreadable, or has no valid positive PID.
|
|
60
|
+
* Exported for testability.
|
|
61
|
+
*/
|
|
62
|
+
export function readLockPid(lockPath, platform) {
|
|
63
|
+
let raw;
|
|
64
|
+
if (platform === 'win32') {
|
|
65
|
+
try {
|
|
66
|
+
raw = readFileSync(lockPath, 'utf8');
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
// First line: `PID\nhostname\n`. Tolerate CRLF.
|
|
72
|
+
raw = raw.split(/\r?\n/, 1)[0]?.trim() ?? '';
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
let target;
|
|
76
|
+
try {
|
|
77
|
+
target = readlinkSync(lockPath);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
raw = target;
|
|
83
|
+
}
|
|
84
|
+
const match = PID_REGEX.exec(raw);
|
|
85
|
+
if (!match)
|
|
86
|
+
return null;
|
|
87
|
+
const pid = Number(match[0]);
|
|
88
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : null;
|
|
89
|
+
}
|
|
90
|
+
function isProcessDead(pid) {
|
|
91
|
+
try {
|
|
92
|
+
process.kill(pid, 0);
|
|
93
|
+
return false; // alive
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const code = error?.code;
|
|
97
|
+
if (code === 'ESRCH')
|
|
98
|
+
return true; // dead
|
|
99
|
+
return false; // EPERM, EACCES, or other — keep the lock
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function removeSingletonFiles(profileDir, platform) {
|
|
103
|
+
const joinPath = platform === 'win32' ? joinWin32 : joinPosix;
|
|
104
|
+
for (const name of SINGLETON_LOCK_FILES) {
|
|
105
|
+
try {
|
|
106
|
+
unlinkSync(joinPath(profileDir, name));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// File may not exist; cleanup is best-effort.
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Iterates every `mcp-chromium-*` profile directory under the platform cache
|
|
115
|
+
* directory and removes the `SingletonLock` / `SingletonCookie` /
|
|
116
|
+
* `SingletonSocket` files whose owning PID is no longer alive.
|
|
117
|
+
*
|
|
118
|
+
* Safety guarantees:
|
|
119
|
+
* - Skips the cache directory silently if it does not exist.
|
|
120
|
+
* - Skips entries whose lock file is missing or unreadable.
|
|
121
|
+
* - Skips entries whose owning PID is still alive.
|
|
122
|
+
* - Skips entries whose PID status is indeterminate (EPERM, etc.).
|
|
123
|
+
* - Skips entries with malformed PID values (negative, zero, non-integer).
|
|
124
|
+
*/
|
|
125
|
+
export function cleanStaleSingletonLocks(options = {}) {
|
|
126
|
+
const platform = options.platform ?? process.platform;
|
|
127
|
+
const cacheDir = options.cacheDir ?? getCacheDir(platform);
|
|
128
|
+
if (!existsSync(cacheDir))
|
|
129
|
+
return;
|
|
130
|
+
let entries;
|
|
131
|
+
try {
|
|
132
|
+
entries = readdirSync(cacheDir);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const joinPath = platform === 'win32' ? joinWin32 : joinPosix;
|
|
138
|
+
for (const entry of entries) {
|
|
139
|
+
if (!entry.startsWith(PROFILE_DIR_PREFIX))
|
|
140
|
+
continue;
|
|
141
|
+
const profileDir = joinPath(cacheDir, entry);
|
|
142
|
+
const lockPath = joinPath(profileDir, 'SingletonLock');
|
|
143
|
+
const pid = readLockPid(lockPath, platform);
|
|
144
|
+
if (pid === null)
|
|
145
|
+
continue;
|
|
146
|
+
if (!isProcessDead(pid))
|
|
147
|
+
continue;
|
|
148
|
+
removeSingletonFiles(profileDir, platform);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=singleton-lock-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton-lock-cleanup.js","sourceRoot":"","sources":["../../src/cli/singleton-lock-cleanup.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import process from 'node:process';
|
|
4
|
-
import { createDoctorReport, renderDoctorReport } from '
|
|
5
|
-
import { createCliCommand, readCliOptions } from '
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { createDoctorReport, renderDoctorReport } from '#src/cli/doctor';
|
|
5
|
+
import { createCliCommand, readCliOptions } from '#src/cli/options';
|
|
6
|
+
import { cleanStaleSingletonLocks } from '#src/cli/singleton-lock-cleanup';
|
|
7
|
+
import { BRIDGE_TRANSPORT_STREAMABLE_HTTP } from '#src/http/options';
|
|
8
|
+
import { startStreamableHttpBridge } from '#src/http/server';
|
|
9
|
+
import { createBridgeLogger } from '#src/logging/logger';
|
|
10
|
+
import { PROJECT_METADATA } from '#src/project/metadata';
|
|
11
|
+
import { startBridge } from '#src/server';
|
|
9
12
|
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
10
13
|
async function main() {
|
|
11
14
|
const command = createCliCommand(pkg.version, {
|
|
@@ -26,9 +29,13 @@ async function main() {
|
|
|
26
29
|
websiteUrl: PROJECT_METADATA.websiteUrl,
|
|
27
30
|
icons: PROJECT_METADATA.icons,
|
|
28
31
|
};
|
|
29
|
-
const running = options.transport ===
|
|
30
|
-
? await
|
|
31
|
-
|
|
32
|
+
const running = options.transport === BRIDGE_TRANSPORT_STREAMABLE_HTTP
|
|
33
|
+
? await startStreamableHttpCliBridge({
|
|
34
|
+
...options.http,
|
|
35
|
+
serverInfo,
|
|
36
|
+
runtimeOptions: options.bridge,
|
|
37
|
+
})
|
|
38
|
+
: await startStdioBridge(serverInfo, options.bridge);
|
|
32
39
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
33
40
|
process.once(signal, () => {
|
|
34
41
|
void running.close().finally(() => process.exit(0));
|
|
@@ -37,12 +44,22 @@ async function main() {
|
|
|
37
44
|
});
|
|
38
45
|
await command.parseAsync(process.argv);
|
|
39
46
|
}
|
|
40
|
-
async function startStdioBridge(serverInfo) {
|
|
41
|
-
|
|
47
|
+
async function startStdioBridge(serverInfo, runtimeOptions) {
|
|
48
|
+
cleanStaleSingletonLocks();
|
|
49
|
+
const bridge = await startBridge({ serverInfo, runtimeOptions });
|
|
42
50
|
return {
|
|
43
51
|
close: () => bridge.dispose(),
|
|
44
52
|
};
|
|
45
53
|
}
|
|
54
|
+
async function startStreamableHttpCliBridge(options) {
|
|
55
|
+
const logger = createBridgeLogger();
|
|
56
|
+
const bridge = await startStreamableHttpBridge({
|
|
57
|
+
...options,
|
|
58
|
+
logger,
|
|
59
|
+
});
|
|
60
|
+
logger.info({ url: bridge.url }, 'streamable-http listening');
|
|
61
|
+
return bridge;
|
|
62
|
+
}
|
|
46
63
|
void main().catch((error) => {
|
|
47
64
|
process.stderr.write(`fatal: ${error.message}\n`);
|
|
48
65
|
process.exit(1);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAEvF,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE;QAC5C,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CACnF,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;gBAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACtD,CAAC;KACF,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,gBAAgB,CAAC,OAAO;YAC9B,KAAK,EAAE,gBAAgB,CAAC,KAAK;YAC7B,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,WAAW,EAAE,gBAAgB,CAAC,WAAW;YACzC,UAAU,EAAE,gBAAgB,CAAC,UAAU;YACvC,KAAK,EAAE,gBAAgB,CAAC,KAAK;SAC9B,CAAC;QAEF,MAAM,OAAO,GACX,OAAO,CAAC,SAAS,KAAK,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|