@comecaramelos/dsh-chrome-mcp 1.0.0 → 2.0.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 +44 -39
- package/lib/client.js +2186 -614
- package/lib/client.js.map +4 -4
- package/lib/host/apply.d.ts +38 -1
- package/lib/host/apply.d.ts.map +1 -1
- package/lib/host/apply.js +43 -17
- package/lib/host/apply.js.map +1 -1
- package/lib/host/bridge.d.ts +28 -19
- package/lib/host/bridge.d.ts.map +1 -1
- package/lib/host/bridge.js +71 -79
- package/lib/host/bridge.js.map +1 -1
- package/lib/host/catalog.d.ts +2 -2
- package/lib/host/catalog.js +2 -2
- package/lib/host/commands/chrome-path.d.ts +4 -0
- package/lib/host/commands/chrome-path.d.ts.map +1 -0
- package/lib/host/commands/chrome-path.js +65 -0
- package/lib/host/commands/chrome-path.js.map +1 -0
- package/lib/host/commands/chrome-refresh.d.ts +17 -0
- package/lib/host/commands/chrome-refresh.d.ts.map +1 -0
- package/lib/host/commands/chrome-refresh.js +37 -0
- package/lib/host/commands/chrome-refresh.js.map +1 -0
- package/lib/host/commands/index.d.ts +26 -0
- package/lib/host/commands/index.d.ts.map +1 -0
- package/lib/host/commands/index.js +41 -0
- package/lib/host/commands/index.js.map +1 -0
- package/lib/host/constants.d.ts +107 -30
- package/lib/host/constants.d.ts.map +1 -1
- package/lib/host/constants.js +107 -30
- package/lib/host/constants.js.map +1 -1
- package/lib/host/controller/_trace.d.ts +3 -0
- package/lib/host/controller/_trace.d.ts.map +1 -0
- package/lib/host/controller/_trace.js +14 -0
- package/lib/host/controller/_trace.js.map +1 -0
- package/lib/host/controller/bridge-run.d.ts +4 -2
- package/lib/host/controller/bridge-run.d.ts.map +1 -1
- package/lib/host/controller/bridge-run.js +24 -8
- package/lib/host/controller/bridge-run.js.map +1 -1
- package/lib/host/controller/captures.d.ts +9 -16
- package/lib/host/controller/captures.d.ts.map +1 -1
- package/lib/host/controller/captures.js +73 -48
- package/lib/host/controller/captures.js.map +1 -1
- package/lib/host/controller/commits.d.ts +2 -2
- package/lib/host/controller/commits.d.ts.map +1 -1
- package/lib/host/controller/commits.js +97 -41
- package/lib/host/controller/commits.js.map +1 -1
- package/lib/host/controller/connections.d.ts +38 -0
- package/lib/host/controller/connections.d.ts.map +1 -0
- package/lib/host/controller/connections.js +71 -0
- package/lib/host/controller/connections.js.map +1 -0
- package/lib/host/controller/controller.d.ts +19 -24
- package/lib/host/controller/controller.d.ts.map +1 -1
- package/lib/host/controller/controller.js +181 -114
- package/lib/host/controller/controller.js.map +1 -1
- package/lib/host/controller/index.d.ts +18 -14
- package/lib/host/controller/index.d.ts.map +1 -1
- package/lib/host/controller/index.js +16 -14
- package/lib/host/controller/index.js.map +1 -1
- package/lib/host/controller/notes.d.ts +9 -9
- package/lib/host/controller/notes.d.ts.map +1 -1
- package/lib/host/controller/notes.js +16 -21
- package/lib/host/controller/notes.js.map +1 -1
- package/lib/host/controller/persist.d.ts +10 -3
- package/lib/host/controller/persist.d.ts.map +1 -1
- package/lib/host/controller/persist.js +89 -42
- package/lib/host/controller/persist.js.map +1 -1
- package/lib/host/controller/publish.d.ts +4 -0
- package/lib/host/controller/publish.d.ts.map +1 -0
- package/lib/host/controller/publish.js +56 -0
- package/lib/host/controller/publish.js.map +1 -0
- package/lib/host/controller/runs.d.ts +34 -10
- package/lib/host/controller/runs.d.ts.map +1 -1
- package/lib/host/controller/runs.js +241 -58
- package/lib/host/controller/runs.js.map +1 -1
- package/lib/host/controller/state.d.ts +122 -20
- package/lib/host/controller/state.d.ts.map +1 -1
- package/lib/host/controller/windows-run.d.ts +10 -2
- package/lib/host/controller/windows-run.d.ts.map +1 -1
- package/lib/host/controller/windows-run.js +66 -35
- package/lib/host/controller/windows-run.js.map +1 -1
- package/lib/host/discovery/candidates.d.ts +23 -13
- package/lib/host/discovery/candidates.d.ts.map +1 -1
- package/lib/host/discovery/candidates.js +20 -8
- package/lib/host/discovery/candidates.js.map +1 -1
- package/lib/host/discovery/index.d.ts +1 -0
- package/lib/host/discovery/index.d.ts.map +1 -1
- package/lib/host/discovery/index.js +1 -0
- package/lib/host/discovery/index.js.map +1 -1
- package/lib/host/discovery/probe.d.ts +16 -5
- package/lib/host/discovery/probe.d.ts.map +1 -1
- package/lib/host/discovery/probe.js +68 -10
- package/lib/host/discovery/probe.js.map +1 -1
- package/lib/host/discovery/scan.d.ts +14 -9
- package/lib/host/discovery/scan.d.ts.map +1 -1
- package/lib/host/discovery/scan.js +56 -30
- package/lib/host/discovery/scan.js.map +1 -1
- package/lib/host/flags.d.ts +28 -5
- package/lib/host/flags.d.ts.map +1 -1
- package/lib/host/flags.js +75 -7
- package/lib/host/flags.js.map +1 -1
- package/lib/host/kind.d.ts +45 -0
- package/lib/host/kind.d.ts.map +1 -0
- package/lib/host/kind.js +251 -0
- package/lib/host/kind.js.map +1 -0
- package/lib/host/manager.d.ts +21 -0
- package/lib/host/manager.d.ts.map +1 -0
- package/lib/host/manager.js +113 -0
- package/lib/host/manager.js.map +1 -0
- package/lib/host/migration.d.ts +26 -0
- package/lib/host/migration.d.ts.map +1 -0
- package/lib/host/migration.js +127 -0
- package/lib/host/migration.js.map +1 -0
- package/lib/host/plugin-meta.d.ts +12 -3
- package/lib/host/plugin-meta.d.ts.map +1 -1
- package/lib/host/plugin-meta.js +13 -4
- package/lib/host/plugin-meta.js.map +1 -1
- package/lib/host/schema.d.ts +301 -247
- package/lib/host/schema.d.ts.map +1 -1
- package/lib/host/schema.js +145 -120
- package/lib/host/schema.js.map +1 -1
- package/lib/host/settings.d.ts +22 -3
- package/lib/host/settings.d.ts.map +1 -1
- package/lib/host/settings.js +81 -60
- package/lib/host/settings.js.map +1 -1
- package/lib/host/status.d.ts +7 -10
- package/lib/host/status.d.ts.map +1 -1
- package/lib/host/status.js +8 -23
- package/lib/host/status.js.map +1 -1
- package/lib/host/tool.d.ts +13 -7
- package/lib/host/tool.d.ts.map +1 -1
- package/lib/host/tool.js +4 -3
- package/lib/host/tool.js.map +1 -1
- package/lib/host/types/config.d.ts +66 -12
- package/lib/host/types/config.d.ts.map +1 -1
- package/lib/host/types/executable.d.ts +8 -3
- package/lib/host/types/executable.d.ts.map +1 -1
- package/lib/host/types/index.d.ts +5 -4
- package/lib/host/types/index.d.ts.map +1 -1
- package/lib/host/types/services.d.ts +26 -0
- package/lib/host/types/services.d.ts.map +1 -0
- package/lib/host/types/services.js +9 -0
- package/lib/host/types/services.js.map +1 -0
- package/lib/host/types/settings.d.ts +118 -65
- package/lib/host/types/settings.d.ts.map +1 -1
- package/lib/host/types/stderr.d.ts +3 -5
- package/lib/host/types/stderr.d.ts.map +1 -1
- package/lib/host/values.d.ts +152 -37
- package/lib/host/values.d.ts.map +1 -1
- package/lib/host/values.js +304 -112
- package/lib/host/values.js.map +1 -1
- package/lib/host/windows/connect-flags.d.ts +19 -8
- package/lib/host/windows/connect-flags.d.ts.map +1 -1
- package/lib/host/windows/connect-flags.js +50 -20
- package/lib/host/windows/connect-flags.js.map +1 -1
- package/lib/host/windows/index.d.ts +1 -1
- package/lib/host/windows/index.d.ts.map +1 -1
- package/lib/host/windows/index.js +1 -1
- package/lib/host/windows/index.js.map +1 -1
- package/lib/host/windows/paths.d.ts +27 -6
- package/lib/host/windows/paths.d.ts.map +1 -1
- package/lib/host/windows/paths.js +40 -13
- package/lib/host/windows/paths.js.map +1 -1
- package/lib/host/windows/run.d.ts.map +1 -1
- package/lib/host/windows/run.js +3 -2
- package/lib/host/windows/run.js.map +1 -1
- package/lib/index.d.ts +72 -56
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +74 -55
- package/lib/index.js.map +1 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +35 -14
- package/cordis.patch.yml +0 -5
package/lib/host/apply.d.ts
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-half assembly — the wiring file.
|
|
3
|
+
*
|
|
4
|
+
* `apply` is deliberately the only host module that knows the parts exist; each
|
|
5
|
+
* part keeps its own behavior:
|
|
6
|
+
*
|
|
7
|
+
* ./controller/ the live mirror, the executable runs, the Windows run, the
|
|
8
|
+
* capture paths
|
|
9
|
+
* ./manager.ts the `chrome` + `chrome-windows` kinds and the standalone
|
|
10
|
+
* translation — what this component says to the manager
|
|
11
|
+
* ./settings.ts the configuration form's attach + commit routing + id rule
|
|
12
|
+
* ./commands/ the two headless-mirror slash commands
|
|
13
|
+
* ./tool.ts the MCP-side `prelaunch_windows_chrome` trigger
|
|
14
|
+
*
|
|
15
|
+
* The ordering rule that must survive the split: read the live layers through
|
|
16
|
+
* `source()` at commit time, never capture them — cordis starts the `settings`
|
|
17
|
+
* injection callback after `apply` returns, so a captured value would pin every
|
|
18
|
+
* consumer to the row config and no mid-session GUI edit would ever reach a
|
|
19
|
+
* live connection.
|
|
20
|
+
*
|
|
21
|
+
* What changed with the component model: this row **no longer starts a bridge
|
|
22
|
+
* of its own**. It answers live `chrome` / `chrome-windows` connections instead,
|
|
23
|
+
* and answers nothing at all when no manager is mounted. Mounting therefore
|
|
24
|
+
* stands up the machine half (the mirror, the executable catalog, the runs) and
|
|
25
|
+
* registers the kinds; whether anything runs is the pool's decision.
|
|
26
|
+
*
|
|
27
|
+
* @param ctx - plugin context.
|
|
28
|
+
* @param config - validated config (every volatile field a reference).
|
|
29
|
+
*/
|
|
30
|
+
import { type ChromeMcpControllerDeps } from "./controller/index.js";
|
|
1
31
|
import type { ChromeMcpConfig, PluginContext } from "./types/index.js";
|
|
2
|
-
|
|
32
|
+
/**
|
|
33
|
+
* @param deps - the controller's optional host overrides, passed straight
|
|
34
|
+
* through. Nothing ordinary supplies them — the wiring reaches the machine
|
|
35
|
+
* through the controller's own defaults, so this parameter is what lets a test
|
|
36
|
+
* or a diagnostic answer the machine half (the Windows run, the Windows-side
|
|
37
|
+
* executables the run folds into a candidate list) with a known list.
|
|
38
|
+
*/
|
|
39
|
+
export declare function apply(ctx: PluginContext, config: ChromeMcpConfig, deps?: ChromeMcpControllerDeps): void;
|
|
3
40
|
//# sourceMappingURL=apply.d.ts.map
|
package/lib/host/apply.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/host/apply.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/host/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAA6B,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAKhG,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEvE;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,GAAE,uBAA4B,GAAG,IAAI,CAc3G"}
|
package/lib/host/apply.js
CHANGED
|
@@ -1,31 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Host-half assembly — the wiring file.
|
|
3
3
|
*
|
|
4
|
-
* `apply` is deliberately the only host module that knows the
|
|
5
|
-
*
|
|
4
|
+
* `apply` is deliberately the only host module that knows the parts exist; each
|
|
5
|
+
* part keeps its own behavior:
|
|
6
6
|
*
|
|
7
|
-
* ./controller/ the live
|
|
8
|
-
*
|
|
7
|
+
* ./controller/ the live mirror, the executable runs, the Windows run, the
|
|
8
|
+
* capture paths
|
|
9
|
+
* ./manager.ts the `chrome` + `chrome-windows` kinds and the standalone
|
|
10
|
+
* translation — what this component says to the manager
|
|
11
|
+
* ./settings.ts the configuration form's attach + commit routing + id rule
|
|
12
|
+
* ./commands/ the two headless-mirror slash commands
|
|
13
|
+
* ./tool.ts the MCP-side `prelaunch_windows_chrome` trigger
|
|
9
14
|
*
|
|
10
|
-
* The ordering rule that must survive the split: read the live
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* The ordering rule that must survive the split: read the live layers through
|
|
16
|
+
* `source()` at commit time, never capture them — cordis starts the `settings`
|
|
17
|
+
* injection callback after `apply` returns, so a captured value would pin every
|
|
18
|
+
* consumer to the row config and no mid-session GUI edit would ever reach a
|
|
19
|
+
* live connection.
|
|
15
20
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
21
|
+
* What changed with the component model: this row **no longer starts a bridge
|
|
22
|
+
* of its own**. It answers live `chrome` / `chrome-windows` connections instead,
|
|
23
|
+
* and answers nothing at all when no manager is mounted. Mounting therefore
|
|
24
|
+
* stands up the machine half (the mirror, the executable catalog, the runs) and
|
|
25
|
+
* registers the kinds; whether anything runs is the pool's decision.
|
|
19
26
|
*
|
|
20
27
|
* @param ctx - plugin context.
|
|
21
|
-
* @param config - validated
|
|
28
|
+
* @param config - validated config (every volatile field a reference).
|
|
22
29
|
*/
|
|
23
30
|
import { createChromeMcpController } from "./controller/index.js";
|
|
24
|
-
import {
|
|
31
|
+
import { installChromeMcpCommands } from "./commands/index.js";
|
|
32
|
+
import { attachToManager } from "./manager.js";
|
|
33
|
+
import { installChromeMcpForm } from "./settings.js";
|
|
25
34
|
import { installPrelaunchWindowsChromeTool } from "./tool.js";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @param deps - the controller's optional host overrides, passed straight
|
|
37
|
+
* through. Nothing ordinary supplies them — the wiring reaches the machine
|
|
38
|
+
* through the controller's own defaults, so this parameter is what lets a test
|
|
39
|
+
* or a diagnostic answer the machine half (the Windows run, the Windows-side
|
|
40
|
+
* executables the run folds into a candidate list) with a known list.
|
|
41
|
+
*/
|
|
42
|
+
export function apply(ctx, config, deps = {}) {
|
|
43
|
+
const controller = createChromeMcpController(ctx, config, deps);
|
|
44
|
+
// Stand the instance down when the mount goes away: a hot re-apply must not
|
|
45
|
+
// leave the previous instance's late answers (a scheduled retry above all)
|
|
46
|
+
// firing runs no one asked for.
|
|
47
|
+
ctx.effect(() => () => {
|
|
48
|
+
controller.dispose();
|
|
49
|
+
}, "chrome-mcp: controller teardown");
|
|
50
|
+
// The kinds come first, before the form: a connection saved under either
|
|
51
|
+
// kind is answered through them, and a proposal names them by id.
|
|
52
|
+
attachToManager(ctx, controller);
|
|
53
|
+
installChromeMcpForm(ctx, controller);
|
|
29
54
|
installPrelaunchWindowsChromeTool(ctx, controller);
|
|
55
|
+
installChromeMcpCommands(ctx, config, controller);
|
|
30
56
|
}
|
|
31
57
|
//# sourceMappingURL=apply.js.map
|
package/lib/host/apply.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/host/apply.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/host/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,yBAAyB,EAAgC,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,iCAAiC,EAAE,MAAM,WAAW,CAAC;AAG9D;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,GAAkB,EAAE,MAAuB,EAAE,OAAgC,EAAE;IACjG,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAChE,4EAA4E;IAC5E,2EAA2E;IAC3E,gCAAgC;IAChC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QAClB,UAAU,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,EAAE,iCAAiC,CAAC,CAAC;IACtC,yEAAyE;IACzE,kEAAkE;IAClE,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACjC,oBAAoB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtC,iCAAiC,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnD,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACtD,CAAC"}
|
package/lib/host/bridge.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type * as McpClient from "@deepseek-ai/dsh-mcp-client";
|
|
2
2
|
import type { BridgeSpawnOptions, BridgeSpawnResult, BridgeSpawnTarget, BridgeStderrLogPathOptions, BridgeStderrMode, ChromeMcpConfig } from "./types/index.js";
|
|
3
|
+
/** The CLI of the `chrome-devtools-mcp` this package depends on (pinned). */
|
|
4
|
+
export declare function pinnedServerCli(): string;
|
|
5
|
+
/** Whether a row runs the pinned server: it names no launcher of its own (the
|
|
6
|
+
* schema defaults, or blanks). */
|
|
7
|
+
export declare function usesPinnedServer(entry: Pick<ChromeMcpConfig, "command" | "package">): boolean;
|
|
8
|
+
/** The executable one row's server runs under: this Node for the pinned
|
|
9
|
+
* server, the row's own `command` otherwise. */
|
|
10
|
+
export declare function serverCommand(entry: Pick<ChromeMcpConfig, "command" | "package">, execPath?: string): string;
|
|
3
11
|
/**
|
|
4
|
-
* Build the stdio argv tail for one flags list
|
|
5
|
-
* `-y <package> [extraFlags]
|
|
6
|
-
* the
|
|
12
|
+
* Build the stdio argv tail for one flags list — `<pinned cli> [extraFlags]`
|
|
13
|
+
* for the pinned server, `-y <package> [extraFlags]` for a row's own launcher;
|
|
14
|
+
* the argv {@link buildBridgeSpawn} runs after {@link serverCommand}.
|
|
7
15
|
* When `chromePath` is set and the flags do not already carry an executable-path
|
|
8
16
|
* option, `--executablePath=<path>` is appended (upstream option:
|
|
9
17
|
* https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/configuration.md).
|
|
@@ -14,10 +22,12 @@ import type { BridgeSpawnOptions, BridgeSpawnResult, BridgeSpawnTarget, BridgeSt
|
|
|
14
22
|
*/
|
|
15
23
|
export declare function buildServerArgs(entry: ChromeMcpConfig, extraFlags: string[]): string[];
|
|
16
24
|
/**
|
|
17
|
-
* Default location of the bridge stderr log
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
25
|
+
* Default location of the bridge stderr log — `@comecaramelos/dsh-ancesters`'
|
|
26
|
+
* private per-host directory (`mkdtemp`, mode `0700`), one
|
|
27
|
+
* `<serverName>-bridge.log` per bridge, truncated on every spawn. Nothing in it
|
|
28
|
+
* can be planted by another local principal before the first spawn.
|
|
29
|
+
*
|
|
30
|
+
* `options.tmpdir` keeps a flat, deterministic name for tests and diagnostics.
|
|
21
31
|
* @param serverName - the bridge server namespace.
|
|
22
32
|
* @param options - tmpdir/pid overrides for tests and diagnostics.
|
|
23
33
|
*/
|
|
@@ -25,16 +35,16 @@ export declare function bridgeStderrLogPath(serverName: unknown, options?: Bridg
|
|
|
25
35
|
/**
|
|
26
36
|
* Build the stdio spawn target for one bridge run, honouring the effective
|
|
27
37
|
* stderr mode. The MCP stdio transport spawns the child with the default
|
|
28
|
-
* `stderr: "inherit"`, so every line it prints lands on the dsh console.
|
|
29
|
-
* (default)
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* the
|
|
33
|
-
*
|
|
38
|
+
* `stderr: "inherit"`, so every line it prints lands on the dsh console.
|
|
39
|
+
* "log" (default) launches the argv through ancestros' Node wrapper (D5:
|
|
40
|
+
* `process.execPath` + a shipped script, the same route on Linux, WSL and
|
|
41
|
+
* Windows): stdout keeps flowing as the MCP protocol stream, stderr goes to
|
|
42
|
+
* the log file, the argv reaches the child verbatim. "console" returns the raw
|
|
43
|
+
* command/args (inherited console output).
|
|
34
44
|
* @param target - { command, args, stderr?, logPath?, serverName? }.
|
|
35
|
-
* @param options -
|
|
36
|
-
* @returns { command, args, redirect
|
|
37
|
-
*
|
|
45
|
+
* @param options - execPath/tmpdir/pid overrides for tests.
|
|
46
|
+
* @returns { command, args, redirect } — the log file when redirected, "" when
|
|
47
|
+
* the console echoes. There is no fallback left: Node is always there.
|
|
38
48
|
*/
|
|
39
49
|
export declare function buildBridgeSpawn(target: BridgeSpawnTarget, options?: BridgeSpawnOptions): BridgeSpawnResult;
|
|
40
50
|
/**
|
|
@@ -43,19 +53,18 @@ export declare function buildBridgeSpawn(target: BridgeSpawnTarget, options?: Br
|
|
|
43
53
|
* (`npx -y <package> [extraFlags]`, run as `command`), wrapped through
|
|
44
54
|
* {@link buildBridgeSpawn} so the child's stderr lands in a log file instead of
|
|
45
55
|
* the console when the mode is "log". The returned config carries only
|
|
46
|
-
* dsh-mcp-client fields; `redirect
|
|
56
|
+
* dsh-mcp-client fields; `redirect` describes the wrapper for the
|
|
47
57
|
* host's own diagnostics.
|
|
48
58
|
*/
|
|
49
59
|
export declare function bridgeConfig(entry: ChromeMcpConfig, extraFlags: string[], stderrMode?: BridgeStderrMode): {
|
|
50
60
|
config: McpClient.StdioConfig;
|
|
51
61
|
redirect: string;
|
|
52
|
-
fallback: string;
|
|
53
62
|
};
|
|
54
63
|
/**
|
|
55
64
|
* Wrap a logger so a callback observes every level call before the
|
|
56
65
|
* original runs. Used to capture the nested bridge's own log lines (the only
|
|
57
66
|
* surface dsh-mcp-client exposes for connection failures — reconnect
|
|
58
|
-
* backoff warnings, spawn failures, give-ups) into the
|
|
67
|
+
* backoff warnings, spawn failures, give-ups) into the live mirror.
|
|
59
68
|
* The wrapper shares the underlying LoggerService (exporters/buffer included)
|
|
60
69
|
* and only shadows the level methods.
|
|
61
70
|
* @param base - the base logger to wrap (cordis LoggerService).
|
package/lib/host/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/host/bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/host/bridge.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,KAAK,SAAS,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EACR,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EAClB,MAAM,kBAAkB,CAAC;AAO1B,6EAA6E;AAC7E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;kCACkC;AAClC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,CAAC,GAAG,OAAO,CAI7F;AAED;gDACgD;AAChD,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,CAAC,EAAE,QAAQ,GAAE,MAAyB,GAAG,MAAM,CAE9H;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAUtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAEzG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CAY/G;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,gBAAgB;;;EAwBvG;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,EACrD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAC/C,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAcjD"}
|
package/lib/host/bridge.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The nested `dsh-mcp-client` bridge: its stdio argv + config, the stderr
|
|
3
3
|
* capture wrapper, and the logger wrapper that captures its own log lines into
|
|
4
|
-
* the
|
|
4
|
+
* the live mirror.
|
|
5
5
|
*
|
|
6
6
|
* The bridge's *logical* argv is the public contract the tests and the README
|
|
7
|
-
* quote
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* quote. By default it is the `chrome-devtools-mcp` this package depends on,
|
|
8
|
+
* pinned, run by the same Node that runs the host —
|
|
9
|
+
* `<node> <chrome-devtools-mcp cli> [extraFlags]`, the way dsh's own
|
|
10
|
+
* chrome-devtools provider runs it: no `npx`, no registry on every start, the
|
|
11
|
+
* same route on Linux, WSL and Windows (breaking in 2.0). A row that names its
|
|
12
|
+
* own `command` or `package` keeps `<command> -y <package> [extraFlags]`.
|
|
13
|
+
* `--executablePath=<chromePath>` is appended only when a path is configured
|
|
14
|
+
* and the flags list does not already pin an executable. In the default "log"
|
|
15
|
+
* stderr mode that argv is not spawned
|
|
16
|
+
* raw: {@link buildBridgeSpawn} launches it through ancestros' Node wrapper, which
|
|
17
|
+
* hands the argv over verbatim (the child never sees the wrapper) and sends only
|
|
12
18
|
* stderr into a per-spawn log file, leaving stdout to carry the MCP protocol
|
|
13
19
|
* stream. Without this wrapper every startup/progress line npx prints would
|
|
14
20
|
* land directly on the dsh console — exactly what makes the connection feel
|
|
@@ -18,29 +24,35 @@
|
|
|
18
24
|
* only through `ctx.logger`: without it the card would never surface a
|
|
19
25
|
* failed/recovered bridge.
|
|
20
26
|
*/
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import { LOG_LEVELS, SH_PATH_CANDIDATES } from "./constants.js";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
import { buildSpawn, stderrLogPath } from "@comecaramelos/dsh-ancesters/host";
|
|
29
|
+
import { LOG_LEVELS } from "./constants.js";
|
|
25
30
|
import { carriesExecutablePath, flagsSkipCheck } from "./flags.js";
|
|
31
|
+
import { readConfigField } from "./values.js";
|
|
32
|
+
/** The row defaults that mean "the pinned server": a row that never named its
|
|
33
|
+
* own launcher. */
|
|
34
|
+
const DEFAULT_COMMAND = "npx";
|
|
35
|
+
const DEFAULT_PACKAGE = "chrome-devtools-mcp@latest";
|
|
36
|
+
/** The CLI of the `chrome-devtools-mcp` this package depends on (pinned). */
|
|
37
|
+
export function pinnedServerCli() {
|
|
38
|
+
return fileURLToPath(import.meta.resolve("chrome-devtools-mcp/build/src/bin/chrome-devtools-mcp.js"));
|
|
39
|
+
}
|
|
40
|
+
/** Whether a row runs the pinned server: it names no launcher of its own (the
|
|
41
|
+
* schema defaults, or blanks). */
|
|
42
|
+
export function usesPinnedServer(entry) {
|
|
43
|
+
const command = String(entry.command ?? "").trim();
|
|
44
|
+
const pkg = String(entry.package ?? "").trim();
|
|
45
|
+
return (command === "" || command === DEFAULT_COMMAND) && (pkg === "" || pkg === DEFAULT_PACKAGE);
|
|
46
|
+
}
|
|
47
|
+
/** The executable one row's server runs under: this Node for the pinned
|
|
48
|
+
* server, the row's own `command` otherwise. */
|
|
49
|
+
export function serverCommand(entry, execPath = process.execPath) {
|
|
50
|
+
return usesPinnedServer(entry) ? execPath : String(entry.command);
|
|
51
|
+
}
|
|
26
52
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* missing — otherwise the transport would report a bare exit code and the
|
|
31
|
-
* reason would be buried in the log file.
|
|
32
|
-
*/
|
|
33
|
-
const BRIDGE_STDERR_SHELL_SCRIPT = [
|
|
34
|
-
'BRIDGE="$1"',
|
|
35
|
-
'LOG="$2"',
|
|
36
|
-
"shift 2",
|
|
37
|
-
'command -v "$BRIDGE" >/dev/null 2>&1 || { echo "chrome-devtools-mcp: bridge executable not found: $BRIDGE" >&2; exit 127; }',
|
|
38
|
-
'exec "$BRIDGE" "$@" 2>"$LOG"'
|
|
39
|
-
].join("; ");
|
|
40
|
-
/**
|
|
41
|
-
* Build the stdio argv tail for one flags list:
|
|
42
|
-
* `-y <package> [extraFlags]`, the argv tail {@link buildBridgeSpawn} runs, so
|
|
43
|
-
* the logical invocation is `npx -y chrome-devtools-mcp@latest [extraFlags]`.
|
|
53
|
+
* Build the stdio argv tail for one flags list — `<pinned cli> [extraFlags]`
|
|
54
|
+
* for the pinned server, `-y <package> [extraFlags]` for a row's own launcher;
|
|
55
|
+
* the argv {@link buildBridgeSpawn} runs after {@link serverCommand}.
|
|
44
56
|
* When `chromePath` is set and the flags do not already carry an executable-path
|
|
45
57
|
* option, `--executablePath=<path>` is appended (upstream option:
|
|
46
58
|
* https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/configuration.md).
|
|
@@ -51,72 +63,51 @@ const BRIDGE_STDERR_SHELL_SCRIPT = [
|
|
|
51
63
|
*/
|
|
52
64
|
export function buildServerArgs(entry, extraFlags) {
|
|
53
65
|
const flags = Array.isArray(extraFlags) ? extraFlags.filter((flag) => typeof flag === "string") : [];
|
|
54
|
-
const args = ["-y", entry.package, ...flags];
|
|
55
|
-
|
|
66
|
+
const args = usesPinnedServer(entry) ? [pinnedServerCli(), ...flags] : ["-y", entry.package, ...flags];
|
|
67
|
+
// `chromePath` is a volatile field, so what it carries is either a reference
|
|
68
|
+
// or the value a caller handed in explicitly (the resolved selection).
|
|
69
|
+
const executable = readConfigField(entry.chromePath, "").trim();
|
|
56
70
|
if (executable !== "" && !flags.some((flag) => carriesExecutablePath(flag)) && !flagsSkipCheck(flags)) {
|
|
57
71
|
args.push(`--executablePath=${executable}`);
|
|
58
72
|
}
|
|
59
73
|
return args;
|
|
60
74
|
}
|
|
61
75
|
/**
|
|
62
|
-
* Default location of the bridge stderr log
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
76
|
+
* Default location of the bridge stderr log — `@comecaramelos/dsh-ancesters`'
|
|
77
|
+
* private per-host directory (`mkdtemp`, mode `0700`), one
|
|
78
|
+
* `<serverName>-bridge.log` per bridge, truncated on every spawn. Nothing in it
|
|
79
|
+
* can be planted by another local principal before the first spawn.
|
|
80
|
+
*
|
|
81
|
+
* `options.tmpdir` keeps a flat, deterministic name for tests and diagnostics.
|
|
66
82
|
* @param serverName - the bridge server namespace.
|
|
67
83
|
* @param options - tmpdir/pid overrides for tests and diagnostics.
|
|
68
84
|
*/
|
|
69
85
|
export function bridgeStderrLogPath(serverName, options = {}) {
|
|
70
|
-
|
|
71
|
-
const pid = options.pid === void 0 ? process.pid : options.pid;
|
|
72
|
-
const safe = typeof serverName === "string" ? serverName.replace(/[^A-Za-z0-9_-]/gu, "-") : "bridge";
|
|
73
|
-
return path.join(tmp, `dsh-chrome-mcp-${safe}-bridge-${pid}.log`);
|
|
86
|
+
return stderrLogPath(serverName, options);
|
|
74
87
|
}
|
|
75
88
|
/**
|
|
76
89
|
* Build the stdio spawn target for one bridge run, honouring the effective
|
|
77
90
|
* stderr mode. The MCP stdio transport spawns the child with the default
|
|
78
|
-
* `stderr: "inherit"`, so every line it prints lands on the dsh console.
|
|
79
|
-
* (default)
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* the
|
|
83
|
-
*
|
|
91
|
+
* `stderr: "inherit"`, so every line it prints lands on the dsh console.
|
|
92
|
+
* "log" (default) launches the argv through ancestros' Node wrapper (D5:
|
|
93
|
+
* `process.execPath` + a shipped script, the same route on Linux, WSL and
|
|
94
|
+
* Windows): stdout keeps flowing as the MCP protocol stream, stderr goes to
|
|
95
|
+
* the log file, the argv reaches the child verbatim. "console" returns the raw
|
|
96
|
+
* command/args (inherited console output).
|
|
84
97
|
* @param target - { command, args, stderr?, logPath?, serverName? }.
|
|
85
|
-
* @param options -
|
|
86
|
-
* @returns { command, args, redirect
|
|
87
|
-
*
|
|
98
|
+
* @param options - execPath/tmpdir/pid overrides for tests.
|
|
99
|
+
* @returns { command, args, redirect } — the log file when redirected, "" when
|
|
100
|
+
* the console echoes. There is no fallback left: Node is always there.
|
|
88
101
|
*/
|
|
89
102
|
export function buildBridgeSpawn(target, options = {}) {
|
|
90
|
-
const raw = { command: target.command, args: [...target.args], redirect: "", fallback: "" };
|
|
91
103
|
const mode = target.stderr === void 0 ? "log" : target.stderr;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
fs.accessSync(candidate, fs.constants.X_OK);
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
: options.exists;
|
|
108
|
-
const sh = SH_PATH_CANDIDATES.find((candidate) => exists(candidate));
|
|
109
|
-
if (sh === void 0)
|
|
110
|
-
return { ...raw, fallback: "shell" };
|
|
111
|
-
const logPath = typeof target.logPath === "string" && target.logPath !== ""
|
|
112
|
-
? target.logPath
|
|
113
|
-
: bridgeStderrLogPath(target.serverName ?? "bridge", options);
|
|
114
|
-
return {
|
|
115
|
-
command: sh,
|
|
116
|
-
args: ["-c", BRIDGE_STDERR_SHELL_SCRIPT, "chrome-devtools-mcp", target.command, logPath, ...target.args],
|
|
117
|
-
redirect: logPath,
|
|
118
|
-
fallback: ""
|
|
119
|
-
};
|
|
104
|
+
return buildSpawn({
|
|
105
|
+
command: target.command,
|
|
106
|
+
args: [...target.args],
|
|
107
|
+
stderr: mode,
|
|
108
|
+
...(typeof target.logPath === "string" && target.logPath !== "" ? { logPath: target.logPath } : {}),
|
|
109
|
+
serverName: target.serverName ?? "bridge"
|
|
110
|
+
}, options);
|
|
120
111
|
}
|
|
121
112
|
/**
|
|
122
113
|
* stdio config for the nested mcp-client bridge for one flags list + effective
|
|
@@ -124,12 +115,12 @@ export function buildBridgeSpawn(target, options = {}) {
|
|
|
124
115
|
* (`npx -y <package> [extraFlags]`, run as `command`), wrapped through
|
|
125
116
|
* {@link buildBridgeSpawn} so the child's stderr lands in a log file instead of
|
|
126
117
|
* the console when the mode is "log". The returned config carries only
|
|
127
|
-
* dsh-mcp-client fields; `redirect
|
|
118
|
+
* dsh-mcp-client fields; `redirect` describes the wrapper for the
|
|
128
119
|
* host's own diagnostics.
|
|
129
120
|
*/
|
|
130
121
|
export function bridgeConfig(entry, extraFlags, stderrMode) {
|
|
131
122
|
const spawned = buildBridgeSpawn({
|
|
132
|
-
command: entry
|
|
123
|
+
command: serverCommand(entry),
|
|
133
124
|
args: buildServerArgs(entry, extraFlags),
|
|
134
125
|
stderr: stderrMode === void 0 ? entry.bridgeStderr : stderrMode,
|
|
135
126
|
logPath: entry.bridgeStderrLog,
|
|
@@ -143,16 +134,17 @@ export function bridgeConfig(entry, extraFlags, stderrMode) {
|
|
|
143
134
|
env: entry.env,
|
|
144
135
|
cwd: entry.cwd,
|
|
145
136
|
toolCallTimeoutMs: entry.toolCallTimeoutMs,
|
|
137
|
+
maxInstructionBytes: entry.maxInstructionBytes,
|
|
146
138
|
failOnStartupError: entry.failOnStartupError,
|
|
147
139
|
reconnect: entry.reconnect
|
|
148
140
|
};
|
|
149
|
-
return { config, redirect: spawned.redirect
|
|
141
|
+
return { config, redirect: spawned.redirect };
|
|
150
142
|
}
|
|
151
143
|
/**
|
|
152
144
|
* Wrap a logger so a callback observes every level call before the
|
|
153
145
|
* original runs. Used to capture the nested bridge's own log lines (the only
|
|
154
146
|
* surface dsh-mcp-client exposes for connection failures — reconnect
|
|
155
|
-
* backoff warnings, spawn failures, give-ups) into the
|
|
147
|
+
* backoff warnings, spawn failures, give-ups) into the live mirror.
|
|
156
148
|
* The wrapper shares the underlying LoggerService (exporters/buffer included)
|
|
157
149
|
* and only shadows the level methods.
|
|
158
150
|
* @param base - the base logger to wrap (cordis LoggerService).
|
package/lib/host/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/host/bridge.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/host/bridge.ts"],"names":[],"mappings":"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"}
|
package/lib/host/catalog.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ export declare function entryLabel(entry: ChromeExecutableEntry): string;
|
|
|
11
11
|
/**
|
|
12
12
|
* Coerce anything into well-formed rows: trim both fields, drop ids that cannot
|
|
13
13
|
* go on the wire, keep the first row per id, cap the name, cap the list (the
|
|
14
|
-
* tail drops off). A served array is already normalized; one read straight from
|
|
15
|
-
*
|
|
14
|
+
* tail drops off). A served array is already normalized; one read straight from a
|
|
15
|
+
* form write is not, so the row writer is the place that makes it safe.
|
|
16
16
|
*/
|
|
17
17
|
export declare function normalizeEntries(value: unknown): ChromeExecutableEntry[];
|
|
18
18
|
/**
|
package/lib/host/catalog.js
CHANGED
|
@@ -38,8 +38,8 @@ export function entryLabel(entry) {
|
|
|
38
38
|
/**
|
|
39
39
|
* Coerce anything into well-formed rows: trim both fields, drop ids that cannot
|
|
40
40
|
* go on the wire, keep the first row per id, cap the name, cap the list (the
|
|
41
|
-
* tail drops off). A served array is already normalized; one read straight from
|
|
42
|
-
*
|
|
41
|
+
* tail drops off). A served array is already normalized; one read straight from a
|
|
42
|
+
* form write is not, so the row writer is the place that makes it safe.
|
|
43
43
|
*/
|
|
44
44
|
export function normalizeEntries(value) {
|
|
45
45
|
if (!Array.isArray(value))
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ChromeMcpController } from "../controller/index.js";
|
|
2
|
+
import type { CommandDefinition } from "../types/index.js";
|
|
3
|
+
export declare function createChromePathCommand(controller: ChromeMcpController): CommandDefinition;
|
|
4
|
+
//# sourceMappingURL=chrome-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome-path.d.ts","sourceRoot":"","sources":["../../../src/host/commands/chrome-path.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,mBAAmB,GAAG,iBAAiB,CAgD1F"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/chrome-path` — the headless mirror of the card's executable picker.
|
|
3
|
+
*
|
|
4
|
+
* It answers what the pill states and changes what it changes, reading the saved
|
|
5
|
+
* rows and the live mirror exactly the way the card reads them, and writing the
|
|
6
|
+
* one same persisted `chromePath` field through the controller's write-back
|
|
7
|
+
* channel (`selectChromePath` — `persistChromePath`, i.e. one `settings.mutate`
|
|
8
|
+
* on the row's entry id, the live clear riding along) — never a route of its
|
|
9
|
+
* own. `none` clears the user layer back to what the row config carries under
|
|
10
|
+
* it, which is the same answer a cleared picker reads with. And a path write
|
|
11
|
+
* answers against the same validation gate a GUI write runs through: the
|
|
12
|
+
* field's own schema pattern, so control characters are refused here exactly as
|
|
13
|
+
* they are refused on the card door.
|
|
14
|
+
*/
|
|
15
|
+
import { entryLabel } from "../catalog.js";
|
|
16
|
+
import { CHROME_PATH_PATTERN } from "../constants.js";
|
|
17
|
+
import { readSavedExecutables } from "../values.js";
|
|
18
|
+
const USAGE = "Usage: /chrome-path <path> — select the Chrome executable the row launches by default. Use /chrome-path none to clear the selection back to the row config.";
|
|
19
|
+
export function createChromePathCommand(controller) {
|
|
20
|
+
return {
|
|
21
|
+
name: "chrome-path",
|
|
22
|
+
description: "Show or change the Chrome executable the row launches by default",
|
|
23
|
+
input: { hint: "[<path>|none]" },
|
|
24
|
+
async handler(invocation) {
|
|
25
|
+
const input = invocation.rawInput.trim();
|
|
26
|
+
// No argument answers the question the pill states, with the saved
|
|
27
|
+
// rows the picker would offer beneath it.
|
|
28
|
+
if (input === "") {
|
|
29
|
+
const live = controller.live;
|
|
30
|
+
const saved = readSavedExecutables(controller.source());
|
|
31
|
+
const lines = [
|
|
32
|
+
`Current executable: ${live.effectiveChromePath === "" ? "(nothing)" : live.effectiveChromePath}`,
|
|
33
|
+
`Source: ${live.effectiveSource === "" ? "nothing selected" : live.effectiveSource}.`
|
|
34
|
+
];
|
|
35
|
+
lines.push(saved.length === 0 ? "Saved executables: (none — /chrome-refresh discovers them)." : `Saved executables:\n${saved.map((entry) => ` - ${entryLabel(entry)}`).join("\n")}`);
|
|
36
|
+
lines.push(USAGE);
|
|
37
|
+
return { kind: "success", text: lines.join("\n") };
|
|
38
|
+
}
|
|
39
|
+
// The one cleared write: the user layer answers empty again and the
|
|
40
|
+
// row config's own path stands underneath it.
|
|
41
|
+
if (input === "none") {
|
|
42
|
+
if (controller.live.effectiveChromePath === "" && controller.live.effectiveSource === "") {
|
|
43
|
+
return { kind: "success", text: "No executable is selected — there is nothing to clear." };
|
|
44
|
+
}
|
|
45
|
+
await controller.selectChromePath("");
|
|
46
|
+
return { kind: "success", text: "Executable selection cleared — the row launches by default with whatever the row config carries." };
|
|
47
|
+
}
|
|
48
|
+
// Same gate the field's write runs through (../schema.ts).
|
|
49
|
+
if (!CHROME_PATH_PATTERN.test(input)) {
|
|
50
|
+
return { kind: "error", text: "Invalid executable path: control characters (or a length over the path limit) are never valid." };
|
|
51
|
+
}
|
|
52
|
+
// Already what the bridge runs with: same write the picker makes on
|
|
53
|
+
// a no-change pick — nothing lands anywhere new.
|
|
54
|
+
if (controller.live.effectiveChromePath === input && controller.live.effectiveSource === "selected") {
|
|
55
|
+
return { kind: "success", text: `The row default already stands at ${input}.` };
|
|
56
|
+
}
|
|
57
|
+
await controller.selectChromePath(input);
|
|
58
|
+
return {
|
|
59
|
+
kind: "success",
|
|
60
|
+
text: `Chrome executable selected: ${input} — a default shifts with it: live connections without their own pick re-answer, and the executable run re-runs behind the write.`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=chrome-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome-path.js","sourceRoot":"","sources":["../../../src/host/commands/chrome-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/chrome-refresh` — the headless mirror of the card's **Fetch executables**.
|
|
3
|
+
*
|
|
4
|
+
* One executable run on demand: probe every candidate the row config, what this
|
|
5
|
+
* host carries, the saved rows and the selection carry, and merge what exists
|
|
6
|
+
* into the saved rows. The merge already stands inside the run (see
|
|
7
|
+
* ../controller/runs.ts — `runExecutableDiscovery` merges as its own step), so
|
|
8
|
+
* the headless path needs no merge step of its own: it fires the run and reads
|
|
9
|
+
* the answers off the live mirror the run publishes, never more than the run
|
|
10
|
+
* answered. The bump of `executableDiscoveryRevision` around the awaited run is
|
|
11
|
+
* what tells a reportable run from one that never completed — the statuses on
|
|
12
|
+
* the mirror could otherwise be from the last run.
|
|
13
|
+
*/
|
|
14
|
+
import type { ChromeMcpController } from "../controller/index.js";
|
|
15
|
+
import type { CommandDefinition } from "../types/index.js";
|
|
16
|
+
export declare function createChromeRefreshCommand(controller: ChromeMcpController): CommandDefinition;
|
|
17
|
+
//# sourceMappingURL=chrome-refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome-refresh.d.ts","sourceRoot":"","sources":["../../../src/host/commands/chrome-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,mBAAmB,GAAG,iBAAiB,CAgC7F"}
|