@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.
Files changed (172) hide show
  1. package/README.md +44 -39
  2. package/lib/client.js +2186 -614
  3. package/lib/client.js.map +4 -4
  4. package/lib/host/apply.d.ts +38 -1
  5. package/lib/host/apply.d.ts.map +1 -1
  6. package/lib/host/apply.js +43 -17
  7. package/lib/host/apply.js.map +1 -1
  8. package/lib/host/bridge.d.ts +28 -19
  9. package/lib/host/bridge.d.ts.map +1 -1
  10. package/lib/host/bridge.js +71 -79
  11. package/lib/host/bridge.js.map +1 -1
  12. package/lib/host/catalog.d.ts +2 -2
  13. package/lib/host/catalog.js +2 -2
  14. package/lib/host/commands/chrome-path.d.ts +4 -0
  15. package/lib/host/commands/chrome-path.d.ts.map +1 -0
  16. package/lib/host/commands/chrome-path.js +65 -0
  17. package/lib/host/commands/chrome-path.js.map +1 -0
  18. package/lib/host/commands/chrome-refresh.d.ts +17 -0
  19. package/lib/host/commands/chrome-refresh.d.ts.map +1 -0
  20. package/lib/host/commands/chrome-refresh.js +37 -0
  21. package/lib/host/commands/chrome-refresh.js.map +1 -0
  22. package/lib/host/commands/index.d.ts +26 -0
  23. package/lib/host/commands/index.d.ts.map +1 -0
  24. package/lib/host/commands/index.js +41 -0
  25. package/lib/host/commands/index.js.map +1 -0
  26. package/lib/host/constants.d.ts +107 -30
  27. package/lib/host/constants.d.ts.map +1 -1
  28. package/lib/host/constants.js +107 -30
  29. package/lib/host/constants.js.map +1 -1
  30. package/lib/host/controller/_trace.d.ts +3 -0
  31. package/lib/host/controller/_trace.d.ts.map +1 -0
  32. package/lib/host/controller/_trace.js +14 -0
  33. package/lib/host/controller/_trace.js.map +1 -0
  34. package/lib/host/controller/bridge-run.d.ts +4 -2
  35. package/lib/host/controller/bridge-run.d.ts.map +1 -1
  36. package/lib/host/controller/bridge-run.js +24 -8
  37. package/lib/host/controller/bridge-run.js.map +1 -1
  38. package/lib/host/controller/captures.d.ts +9 -16
  39. package/lib/host/controller/captures.d.ts.map +1 -1
  40. package/lib/host/controller/captures.js +73 -48
  41. package/lib/host/controller/captures.js.map +1 -1
  42. package/lib/host/controller/commits.d.ts +2 -2
  43. package/lib/host/controller/commits.d.ts.map +1 -1
  44. package/lib/host/controller/commits.js +97 -41
  45. package/lib/host/controller/commits.js.map +1 -1
  46. package/lib/host/controller/connections.d.ts +38 -0
  47. package/lib/host/controller/connections.d.ts.map +1 -0
  48. package/lib/host/controller/connections.js +71 -0
  49. package/lib/host/controller/connections.js.map +1 -0
  50. package/lib/host/controller/controller.d.ts +19 -24
  51. package/lib/host/controller/controller.d.ts.map +1 -1
  52. package/lib/host/controller/controller.js +181 -114
  53. package/lib/host/controller/controller.js.map +1 -1
  54. package/lib/host/controller/index.d.ts +18 -14
  55. package/lib/host/controller/index.d.ts.map +1 -1
  56. package/lib/host/controller/index.js +16 -14
  57. package/lib/host/controller/index.js.map +1 -1
  58. package/lib/host/controller/notes.d.ts +9 -9
  59. package/lib/host/controller/notes.d.ts.map +1 -1
  60. package/lib/host/controller/notes.js +16 -21
  61. package/lib/host/controller/notes.js.map +1 -1
  62. package/lib/host/controller/persist.d.ts +10 -3
  63. package/lib/host/controller/persist.d.ts.map +1 -1
  64. package/lib/host/controller/persist.js +89 -42
  65. package/lib/host/controller/persist.js.map +1 -1
  66. package/lib/host/controller/publish.d.ts +4 -0
  67. package/lib/host/controller/publish.d.ts.map +1 -0
  68. package/lib/host/controller/publish.js +56 -0
  69. package/lib/host/controller/publish.js.map +1 -0
  70. package/lib/host/controller/runs.d.ts +34 -10
  71. package/lib/host/controller/runs.d.ts.map +1 -1
  72. package/lib/host/controller/runs.js +241 -58
  73. package/lib/host/controller/runs.js.map +1 -1
  74. package/lib/host/controller/state.d.ts +122 -20
  75. package/lib/host/controller/state.d.ts.map +1 -1
  76. package/lib/host/controller/windows-run.d.ts +10 -2
  77. package/lib/host/controller/windows-run.d.ts.map +1 -1
  78. package/lib/host/controller/windows-run.js +66 -35
  79. package/lib/host/controller/windows-run.js.map +1 -1
  80. package/lib/host/discovery/candidates.d.ts +23 -13
  81. package/lib/host/discovery/candidates.d.ts.map +1 -1
  82. package/lib/host/discovery/candidates.js +20 -8
  83. package/lib/host/discovery/candidates.js.map +1 -1
  84. package/lib/host/discovery/index.d.ts +1 -0
  85. package/lib/host/discovery/index.d.ts.map +1 -1
  86. package/lib/host/discovery/index.js +1 -0
  87. package/lib/host/discovery/index.js.map +1 -1
  88. package/lib/host/discovery/probe.d.ts +16 -5
  89. package/lib/host/discovery/probe.d.ts.map +1 -1
  90. package/lib/host/discovery/probe.js +68 -10
  91. package/lib/host/discovery/probe.js.map +1 -1
  92. package/lib/host/discovery/scan.d.ts +14 -9
  93. package/lib/host/discovery/scan.d.ts.map +1 -1
  94. package/lib/host/discovery/scan.js +56 -30
  95. package/lib/host/discovery/scan.js.map +1 -1
  96. package/lib/host/flags.d.ts +28 -5
  97. package/lib/host/flags.d.ts.map +1 -1
  98. package/lib/host/flags.js +75 -7
  99. package/lib/host/flags.js.map +1 -1
  100. package/lib/host/kind.d.ts +45 -0
  101. package/lib/host/kind.d.ts.map +1 -0
  102. package/lib/host/kind.js +251 -0
  103. package/lib/host/kind.js.map +1 -0
  104. package/lib/host/manager.d.ts +21 -0
  105. package/lib/host/manager.d.ts.map +1 -0
  106. package/lib/host/manager.js +113 -0
  107. package/lib/host/manager.js.map +1 -0
  108. package/lib/host/migration.d.ts +26 -0
  109. package/lib/host/migration.d.ts.map +1 -0
  110. package/lib/host/migration.js +127 -0
  111. package/lib/host/migration.js.map +1 -0
  112. package/lib/host/plugin-meta.d.ts +12 -3
  113. package/lib/host/plugin-meta.d.ts.map +1 -1
  114. package/lib/host/plugin-meta.js +13 -4
  115. package/lib/host/plugin-meta.js.map +1 -1
  116. package/lib/host/schema.d.ts +301 -247
  117. package/lib/host/schema.d.ts.map +1 -1
  118. package/lib/host/schema.js +145 -120
  119. package/lib/host/schema.js.map +1 -1
  120. package/lib/host/settings.d.ts +22 -3
  121. package/lib/host/settings.d.ts.map +1 -1
  122. package/lib/host/settings.js +81 -60
  123. package/lib/host/settings.js.map +1 -1
  124. package/lib/host/status.d.ts +7 -10
  125. package/lib/host/status.d.ts.map +1 -1
  126. package/lib/host/status.js +8 -23
  127. package/lib/host/status.js.map +1 -1
  128. package/lib/host/tool.d.ts +13 -7
  129. package/lib/host/tool.d.ts.map +1 -1
  130. package/lib/host/tool.js +4 -3
  131. package/lib/host/tool.js.map +1 -1
  132. package/lib/host/types/config.d.ts +66 -12
  133. package/lib/host/types/config.d.ts.map +1 -1
  134. package/lib/host/types/executable.d.ts +8 -3
  135. package/lib/host/types/executable.d.ts.map +1 -1
  136. package/lib/host/types/index.d.ts +5 -4
  137. package/lib/host/types/index.d.ts.map +1 -1
  138. package/lib/host/types/services.d.ts +26 -0
  139. package/lib/host/types/services.d.ts.map +1 -0
  140. package/lib/host/types/services.js +9 -0
  141. package/lib/host/types/services.js.map +1 -0
  142. package/lib/host/types/settings.d.ts +118 -65
  143. package/lib/host/types/settings.d.ts.map +1 -1
  144. package/lib/host/types/stderr.d.ts +3 -5
  145. package/lib/host/types/stderr.d.ts.map +1 -1
  146. package/lib/host/values.d.ts +152 -37
  147. package/lib/host/values.d.ts.map +1 -1
  148. package/lib/host/values.js +304 -112
  149. package/lib/host/values.js.map +1 -1
  150. package/lib/host/windows/connect-flags.d.ts +19 -8
  151. package/lib/host/windows/connect-flags.d.ts.map +1 -1
  152. package/lib/host/windows/connect-flags.js +50 -20
  153. package/lib/host/windows/connect-flags.js.map +1 -1
  154. package/lib/host/windows/index.d.ts +1 -1
  155. package/lib/host/windows/index.d.ts.map +1 -1
  156. package/lib/host/windows/index.js +1 -1
  157. package/lib/host/windows/index.js.map +1 -1
  158. package/lib/host/windows/paths.d.ts +27 -6
  159. package/lib/host/windows/paths.d.ts.map +1 -1
  160. package/lib/host/windows/paths.js +40 -13
  161. package/lib/host/windows/paths.js.map +1 -1
  162. package/lib/host/windows/run.d.ts.map +1 -1
  163. package/lib/host/windows/run.js +3 -2
  164. package/lib/host/windows/run.js.map +1 -1
  165. package/lib/index.d.ts +72 -56
  166. package/lib/index.d.ts.map +1 -1
  167. package/lib/index.js +74 -55
  168. package/lib/index.js.map +1 -1
  169. package/locale/en.json +6 -0
  170. package/locale/zh.json +6 -0
  171. package/package.json +35 -14
  172. package/cordis.patch.yml +0 -5
@@ -1,25 +1,9 @@
1
1
  import { type WindowsChromeRunOptions } from "../windows/index.js";
2
- import type { ChromeMcpConfig, PluginContext, SettingsResolved, WindowsChromeRun } from "../types/index.js";
3
- /** The live state one apply() keeps in memory. */
4
- export interface ChromeMcpController {
5
- /** The composition base layer served alongside the user layer. */
6
- readonly entry: SettingsResolved;
7
- /** Swap the live resolved settings source (installSection hook). */
8
- setSource(next: () => SettingsResolved): void;
9
- /** Route one settings commit: relaunch on flag or executable drift, and run
10
- * one executable refresh on the search trigger. */
11
- onSettingsChange(): void;
12
- /** Run one executable refresh (probe the candidates, merge what is found
13
- * into the saved rows, seed a never-configured host). Runs are serialized so
14
- * rapid actions never interleave. */
15
- run(): Promise<unknown>;
16
- /** Run the Windows Chrome path once (locate, prereq, port, launch, connect)
17
- * on the same one-run-at-a-time chain the button drives through, and answer
18
- * with what the run stated. This is the MCP-tool surface of the button: the
19
- * trigger is the call itself — nothing is persisted, so a booting host never
20
- * launches a browser on its own. Resolves after the run settles. */
21
- prelaunchWindowsChrome(): Promise<string>;
22
- }
2
+ import type { ChromeMcpConfig, PluginContext, WindowsChromeRun } from "../types/index.js";
3
+ import type { Controller } from "./state.js";
4
+ /** Public alias: the controller object the form, commands and kinds work
5
+ * through is the internal `Controller` type itself. */
6
+ export type ChromeMcpController = Controller;
23
7
  /**
24
8
  * Optional overrides for tests and diagnostics: the Windows Chrome run is the
25
9
  * only half that reaches outside the process (it opens TCP sockets and spawns
@@ -28,13 +12,24 @@ export interface ChromeMcpController {
28
12
  */
29
13
  export type ChromeMcpControllerDeps = {
30
14
  runWindowsChrome?: (options: WindowsChromeRunOptions) => Promise<WindowsChromeRun>;
15
+ /** The Windows-side executables this host carries, in preference order. The
16
+ * machine half of the candidate fold — the real one locates through the
17
+ * interop mount; a test supplies the answer list it wants folded. */
18
+ windowsExecutables?: () => string[];
19
+ /** The platform the WSL probe reads; defaults to `process.platform`. A test
20
+ * that simulates a WSL host through its launch environment states `linux`
21
+ * here too — the environment alone never makes a Windows host WSL. */
22
+ platform?: NodeJS.Platform;
31
23
  };
32
24
  /**
33
- * Build the live state for one bridge + card pairing.
25
+ * Build the live state for one row page. The controller is also the public
26
+ * surface (`ChromeMcpController` — the same object the form, the commands and
27
+ * the kinds work through); what each method does lives in the sibling modules.
34
28
  * @param ctx - plugin context.
35
- * @param config - validated row config.
29
+ * @param config - the validated config `apply` received: every `.volatile()`
30
+ * field a reference rather than a value (read them through `readConfigField`).
36
31
  * @param deps - optional host overrides (tests replace the Windows run;
37
32
  * everything else resolves from this process).
38
33
  */
39
- export declare function createChromeMcpController(ctx: PluginContext, config: ChromeMcpConfig, deps?: ChromeMcpControllerDeps): ChromeMcpController;
34
+ export declare function createChromeMcpController(ctx: PluginContext, config: ChromeMcpConfig, deps?: ChromeMcpControllerDeps): Controller;
40
35
  //# sourceMappingURL=controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/host/controller/controller.ts"],"names":[],"mappings":"AA6BA,OAAO,EAA2B,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE5F,OAAO,KAAK,EAER,eAAe,EAEf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAS3B,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAChC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,oEAAoE;IACpE,SAAS,CAAC,IAAI,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;IAC9C;uDACmD;IACnD,gBAAgB,IAAI,IAAI,CAAC;IACzB;;yCAEqC;IACrC,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB;;;;wEAIoE;IACpE,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACtF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,GAAE,uBAA4B,GAAG,mBAAmB,CAwI9I"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/host/controller/controller.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAyD,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAY1H,OAAO,KAAK,EACR,eAAe,EAEf,aAAa,EACb,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AAE9D;uDACuD;AACvD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnF;;yEAEqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACpC;;0EAEsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,GAAE,uBAA4B,GAAG,UAAU,CAgMrI"}
@@ -1,122 +1,137 @@
1
1
  /**
2
2
  * Host half — live state: `createChromeMcpController`.
3
3
  *
4
- * One controller per apply(): the composition base layer (`entry`), the live
5
- * resolved settings source, the nested bridge, the serialized executable runs,
6
- * and the two capture paths — bridge log lines and tool-call results. Every
7
- * base-layer mutation happens here; settings commits route in through the
8
- * controller methods, never the other way round.
4
+ * One controller per apply(): the live mirror the Host publishes, the serialized
5
+ * executable runs, the Windows run half, and the capture paths — tool-call
6
+ * results reaching the live mirror. Every live answer is written into
7
+ * `state.live` and published through the volatile references (see ./publish.ts);
8
+ * form commits route in through the controller methods, never the other way
9
+ * round.
9
10
  *
10
- * The executable state follows the reference plugin's picker shape and the rule
11
- * that there is no auto mode: the saved **rows** (`{ id: path, name: label }`)
12
- * are what the card's dropdown lists, the *selection* is what the bridge
13
- * launches with, and a run refreshes both — it probes every candidate the rows
14
- * and the row config carry, merges what it finds into the rows (names kept), and
15
- * seeds a never-configured host exactly once. A fixed path that later breaks
16
- * stays fixed and reads broken instead of being re-resolved.
11
+ * Since the component model, the controller starts nothing: every live bridge is
12
+ * a connection of the manager's, answered through ./kind.ts. What this half owns
13
+ * is the machine — the executable catalog and its runs, the Windows run, the
14
+ * layers, and the mirror — plus the seam the manager reads it through (the
15
+ * connection service sits on `state.connections`, installed by ../manager.ts).
17
16
  *
18
- * This file is only the assembly: it resolves the config-derived pieces, builds
19
- * the base layer, makes the initial bridge connection, and wires the public
20
- * methods to the behavior modules that sit alongside it (see ./index.ts for the
21
- * layout). Everything that actually *does* something lives there, not here.
17
+ * The executable state keeps the rule that there is no auto mode: the saved
18
+ * **rows** (`{ id: path, name: label }`) are what every picker lists, the
19
+ * *selection* is what the default answers run with, and a run refreshes both —
20
+ * it probes every candidate the rows and the row config carry, merges what it
21
+ * finds into the rows (names kept), and seeds a never-configured host exactly
22
+ * once. A fixed path that later breaks stays fixed and reads broken instead of
23
+ * being re-resolved.
24
+ *
25
+ * This file is only the assembly: it resolves the config-derived pieces, seeds
26
+ * the live mirror, and wires the public methods to the behavior modules that sit
27
+ * alongside it (see ./index.ts for the layout). Everything that actually *does*
28
+ * something lives there, not here.
22
29
  */
23
- import * as McpClient from "@deepseek-ai/dsh-mcp-client";
30
+ import { existsSync } from "node:fs";
24
31
  import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
25
- import { bridgeConfig, captureLogger } from "../bridge.js";
26
- import { DEFAULT_EXTRA_FLAGS, FLAGS_ENV_VAR, WSL_EXTRA_FLAGS, WSL_WINDOWS_LAUNCH_ERROR } from "../constants.js";
27
- import { extractExecutablePathFlag, flagsSkipCheck, stripExecutablePathFlags } from "../flags.js";
32
+ import { FLAGS_ENV_VAR, WSL_WINDOWS_LAUNCH_ERROR } from "../constants.js";
33
+ import { flagsSkipCheck } from "../flags.js";
28
34
  import { isWindowsExecutablePath, isWindowsSubsystemForLinux } from "../platform.js";
29
- import { runWindowsChromeConnect } from "../windows/index.js";
30
- import { readPersistedChromePath, readPersistedFlags, readPersistedStderrMode, resolveEnvFlags, resolveStderrMode } from "../values.js";
31
- import { configForBridge } from "./bridge-run.js";
32
- import { noteBridgeLog, registerToolCapture } from "./captures.js";
33
- import { onSettingsChange } from "./commits.js";
34
- import { noteSelection, noteStderr } from "./notes.js";
35
- import { prelaunchWindowsChrome, queue } from "./runs.js";
35
+ import { findWindowsChromeExecutables, runWindowsChromeConnect } from "../windows/index.js";
36
+ import { createLiveMirror, readConfigForm, readConfigLayers, readDefaultExtraFlags, readWslExtraFlags, resolveEnvFlags, resolveLaunchFlags, resolveSelection, resolveStderrModeFromLayers } from "../values.js";
37
+ import { registerToolCapture } from "./captures.js";
38
+ import { noteRunning as mirrorRunning } from "./connections.js";
39
+ import { onFormCommit } from "./commits.js";
40
+ import { noteSelection } from "./notes.js";
41
+ import { dismissMigration, } from "./persist.js";
42
+ import { cancelDiscoveryRetry, prelaunchWindowsChrome, queue, selectChromePath } from "./runs.js";
43
+ import { prelaunchWindowsForConnection } from "./windows-run.js";
36
44
  /**
37
- * Build the live state for one bridge + card pairing.
45
+ * Build the live state for one row page. The controller is also the public
46
+ * surface (`ChromeMcpController` — the same object the form, the commands and
47
+ * the kinds work through); what each method does lives in the sibling modules.
38
48
  * @param ctx - plugin context.
39
- * @param config - validated row config.
49
+ * @param config - the validated config `apply` received: every `.volatile()`
50
+ * field a reference rather than a value (read them through `readConfigField`).
40
51
  * @param deps - optional host overrides (tests replace the Windows run;
41
52
  * everything else resolves from this process).
42
53
  */
43
54
  export function createChromeMcpController(ctx, config, deps = {}) {
44
- // The Windows run half — injectable for wiring tests, default is the real
45
- // one (TCP samples + the interop launch).
55
+ // The Windows run half — injectable for tests, default is the real one (TCP
56
+ // samples + the interop launch).
46
57
  const windowsChrome = typeof deps.runWindowsChrome === "function" ? deps.runWindowsChrome : runWindowsChromeConnect;
47
58
  const launchEnvironment = launchEnvironmentOf(ctx);
48
- const envValue = launchEnvironment.get(FLAGS_ENV_VAR)?.value;
59
+ const launchFlags = launchEnvironment.get(FLAGS_ENV_VAR)?.value;
49
60
  // Where the plugin runs: a WSL host plus a Windows executable is a selection
50
- // the bridge can never launch (its debug pipes do not cross the interop
61
+ // the local bridge can never launch (its debug pipes do not cross the interop
51
62
  // boundary, and its debugging port stays on the Windows loopback). The launch
52
63
  // environment is authoritative inside a host, so the answer is deterministic;
53
64
  // a bare call falls back to the interop marker.
54
- const wslHost = isWindowsSubsystemForLinux({ env: (name) => launchEnvironment.get(name)?.value });
65
+ const wslHost = isWindowsSubsystemForLinux({ platform: deps.platform, env: (name) => launchEnvironment.get(name)?.value });
66
+ // The Linux half of the host: the executable candidate list models the
67
+ // stable-channel installs a Linux host carries, so this is what keys the
68
+ // executable-missing answer's advice (see runs.ts). WSL is the case with the
69
+ // Windows-side alternative next to it.
70
+ const linuxHost = process.platform === "linux";
55
71
  // A path this host must never exec. There is only one: a Windows
56
72
  // `chrome.exe` selected on a WSL host. Its `--version` probe answers (so the
57
73
  // selection looks healthy) but answering attaches to the Windows browser
58
74
  // session, and that **starts a browser instance** no tool call could drive —
59
- // see WSL_WINDOWS_LAUNCH_ERROR. The run keeps such an entry visible carrying
75
+ // see WSL_WINDOWS_LAUNCH_ERROR. The runs keep such an entry visible carrying
60
76
  // this reason; the probe answers nothing instead of paying for it.
61
77
  const blockedForPlatform = (candidate) => wslHost && isWindowsExecutablePath(candidate) ? WSL_WINDOWS_LAUNCH_ERROR : "";
62
- // A row-level `--executablePath` used to be the only way to pin an
63
- // executable. The picker owns it now, so the flag is read out of the row
64
- // flags here — it becomes the row-config source of the selection, and the
65
- // flag itself never reaches argv as a second source of truth.
66
- const rowChromePath = config.chromePath.trim() !== "" ? config.chromePath.trim() : extractExecutablePathFlag(config.extraFlags);
67
- const rowFlags = stripExecutablePathFlags(config.extraFlags);
68
- if (rowChromePath !== "" && config.chromePath.trim() === "" && extractExecutablePathFlag(config.extraFlags) !== "") {
69
- ctx.logger.warn(`chrome-devtools-mcp(${config.serverName}): an extraFlags "--executablePath" in the row config is now the \`chromePath\` source ("${rowChromePath}"); the flag itself is dropped from the bridge argv`);
70
- }
71
- const baseFlags = resolveEnvFlags(rowFlags, envValue);
72
- if (typeof envValue === "string" && envValue.trim() !== "" && baseFlags === rowFlags) {
73
- ctx.logger.warn(`chrome-devtools-mcp(${config.serverName}): ignoring ${FLAGS_ENV_VAR} — invalid flags list; using row config`);
78
+ // The Windows-side executables this host carries, located through the interop
79
+ // mount. An executable run folds them into its candidate list so the picker
80
+ // can name the Windows browser the **Prelaunch Windows Chrome** run drives
81
+ // instead of hiding it. Being offered only, they are never spawned (see
82
+ // `blockedForPlatform`): an entry answers a note, never a version, and never
83
+ // seeds. Locating them is the machine half of the fold, injected the same way
84
+ // the run's own `exists` half is — a host off WSL answers nothing, and a
85
+ // machine that carries none of them answers nothing either.
86
+ const windowsExecutables = typeof deps.windowsExecutables === "function"
87
+ ? deps.windowsExecutables
88
+ : () => (wslHost ? findWindowsChromeExecutables(existsSync) : []);
89
+ // The configuration form's layers as they answer right now. The references
90
+ // resolve the user layer over the row config, so every answer here is the
91
+ // effective one; the two layers the "did the user say this, or is it the row
92
+ // config" distinction reads only answer once the form attaches, and the first
93
+ // commit read settles it.
94
+ const layers = readConfigLayers(config);
95
+ // Default launch flags (highest first): the user layer,
96
+ // `DSH_CHROME_MCP_FLAGS`, the row config, the schema default. What a
97
+ // connection with no own answer is resolved with starts on them.
98
+ const initialFlags = resolveLaunchFlags(layers, launchFlags);
99
+ if (typeof launchFlags === "string" && launchFlags.trim() !== "" && resolveEnvFlags([], launchFlags).length === 0) {
100
+ ctx.logger.warn(`dsh-chrome-mcp(${config.serverName}): ignoring ${FLAGS_ENV_VAR} — invalid flags list; using the resolved configuration`);
74
101
  }
75
- // The persisted UI selection wins over env/row config: seed the first bridge
76
- // spawn with it. When the settings service is not up yet this yields the base
77
- // flags, and the installSection initial onChange below switches the bridge to
78
- // the persisted selection in place right after.
79
- const initialFlags = readPersistedFlags(ctx) ?? baseFlags;
80
- // The initial selection: persisted `chromePath` → row config → nothing.
81
- // Nothing here consults discovery: the first run does, and only seeds if both
82
- // layers are silent.
83
- const persistedChromePath = readPersistedChromePath(ctx);
84
- const runningChromePath = persistedChromePath !== "" ? persistedChromePath : rowChromePath;
85
- const runningChromeSource = persistedChromePath !== "" ? "selected" : rowChromePath !== "" ? "row-config" : "";
86
- // The effective bridge stderr mode: the persisted UI toggle when set, else the
87
- // row-config `bridgeStderr`. Every spawn reads it, and a UI write hot-switches
88
- // it (restarting the connection).
89
- const runningStderrMode = resolveStderrMode(readPersistedStderrMode(ctx), config.bridgeStderr);
90
- // Composition base layer: part of the resolved value served to the client but
91
- // never persisted. See ./types/index.ts (SettingsBaseLayer) for the whole
92
- // shape; the static `defaultExtraFlags`/`wslExtraFlags` mirrors feed the card's
93
- // Restore defaults / Flags WSL actions, and `windowsChromeStatus` reads off
94
- // this host from the start (the Windows path simply does not exist off WSL).
95
- const entry = {
96
- extraFlags: initialFlags,
97
- refreshExecutablesNonce: 0,
98
- openWindowsChromeNonce: 0,
99
- chromePath: "",
100
- executables: [],
101
- chromeCustomPaths: [],
102
- stderrMode: "",
103
- lastError: "",
104
- chromeMissing: false,
105
- executableDiscoveryRevision: 0,
106
- chromeVersion: "",
107
- executableStatus: [],
108
- effectiveChromePath: runningChromePath,
109
- effectiveSource: runningChromeSource,
110
- wslWindowsExecutable: wslHost && isWindowsExecutablePath(runningChromePath),
111
- rowStderr: config.bridgeStderr === "console" ? "console" : "log",
112
- defaultExtraFlags: [...DEFAULT_EXTRA_FLAGS],
113
- wslExtraFlags: [...WSL_EXTRA_FLAGS],
114
- windowsChromeStatus: { state: wslHost ? "off" : "not-applicable", port: 0, error: "" },
115
- carriesConnectionMode: flagsSkipCheck(initialFlags)
116
- };
102
+ // The initial selection: what the user layer says, else what the row config
103
+ // says (a legacy row-level `--executablePath` folded in — the picker owns that
104
+ // flag, so it becomes the row-config source of the selection and never reaches
105
+ // argv as a second source of truth), else nothing. Nothing here consults
106
+ // discovery: the first run does, and only seeds when both layers are silent.
107
+ const selection = resolveSelection(layers);
108
+ const runningChromePath = selection.path;
109
+ const runningChromeSource = selection.source;
110
+ // The effective console-output mode: what the user layer's toggle says, then
111
+ // what the row config carries, then the row's `bridgeStderr`. Every spawn
112
+ // wrapper reads it.
113
+ const runningStderrMode = resolveStderrModeFromLayers(layers, config.bridgeStderr);
114
+ // The mirror's opening answers: what the default answers would run with, not
115
+ // what a host with no answers would serve. `windowsChromeStatus` in particular
116
+ // reads off this host from the start — the Windows path simply does not exist
117
+ // off WSL.
118
+ const live = createLiveMirror();
119
+ live.effectiveChromePath = runningChromePath;
120
+ live.effectiveSource = runningChromeSource;
121
+ live.stderrEffective = runningStderrMode;
122
+ live.wslWindowsExecutable = wslHost && runningChromePath !== "" && isWindowsExecutablePath(runningChromePath);
123
+ live.carriesConnectionMode = flagsSkipCheck(initialFlags);
124
+ live.windowsChromeStatus = { state: wslHost ? "off" : "not-applicable", port: 0, error: "" };
125
+ live.defaultExtraFlags = readDefaultExtraFlags();
126
+ live.wslExtraFlags = readWslExtraFlags();
117
127
  const state = {
118
- entry,
119
- source: () => entry,
128
+ live,
129
+ form: void 0,
130
+ // The live layers read: the references answer what runs now, and once the
131
+ // form is described the two layers answer the distinction with it. This is
132
+ // read live on every commit — cordis starts the `settings` injection
133
+ // callback after `apply` returns, so nothing may be captured here.
134
+ source: () => readConfigLayers(config, state.form?.settings ? readConfigForm(state.form.settings, state.form.entryId) : void 0),
120
135
  runningFlags: initialFlags,
121
136
  runningStderrMode,
122
137
  runningChromePath,
@@ -128,40 +143,92 @@ export function createChromeMcpController(ctx, config, deps = {}) {
128
143
  seededPath: "",
129
144
  seenUserSelection: false,
130
145
  runs: Promise.resolve(),
146
+ retryTimer: void 0,
147
+ retriesPending: 0,
148
+ disposed: false,
131
149
  wslNoticeShown: false,
132
150
  profileLinkKeptShown: false,
133
- legacyPathsMerged: false
151
+ legacyPathsMerged: false,
152
+ legacyPinAnnounced: false,
153
+ mirror: void 0,
154
+ kindsNotifyQueued: false,
155
+ // The manager seam opens empty: `attachToManager` fills it in once the
156
+ // service answers. A component without the manager answers its own page
157
+ // and starts nothing — exactly as a row with no connections should.
158
+ connections: void 0,
159
+ notifyKindsChanged: () => void 0
134
160
  };
135
161
  const controller = {
136
162
  ctx,
137
163
  config,
138
164
  wslHost,
165
+ linuxHost,
139
166
  blockedForPlatform,
140
- rowChromePath,
141
- rowFlags,
167
+ launchFlags,
142
168
  windowsChrome,
143
- bridge: undefined,
144
- state
145
- };
146
- // Initial connection with the resolved flags + the resolved selection. The
147
- // bridge-log capture rides only on the bridge scope: our own logs bypass it,
148
- // so our own warns never masquerade as connection errors.
149
- const bridgeScope = ctx.extend({ logger: captureLogger(ctx.logger, (level, args) => noteBridgeLog(controller, level, args)) });
150
- const initial = bridgeConfig(configForBridge(controller, initialFlags), initialFlags, runningStderrMode);
151
- noteStderr(controller, initial);
152
- controller.bridge = bridgeScope.plugin(McpClient, initial.config);
153
- noteSelection(controller);
154
- // Tool-level status: browser-level failures are returned to the calling agent
155
- // and never reach the bridge logger.
156
- registerToolCapture(controller);
157
- return {
158
- entry,
159
- setSource: (next) => {
160
- state.source = next;
169
+ windowsExecutables,
170
+ state,
171
+ attachForm(form) {
172
+ state.form = form;
173
+ const nowDescribed = form.settings !== void 0;
174
+ // The first attach is the mount's commit read: no nonce has been
175
+ // observed yet, so its nonce diff fires the registration run. The step
176
+ // where the row starts being *described* is routed too, for the one
177
+ // thing the references cannot answer: which layer a value came from.
178
+ // Until it answers there, the launch environment sits above whatever
179
+ // the references carry, so a saved UI edit has to be re-read against
180
+ // the user layer the moment that layer exists.
181
+ const first = !routed;
182
+ const layersArrived = nowDescribed && !described;
183
+ routed = true;
184
+ described = nowDescribed;
185
+ if (!first && !layersArrived)
186
+ return;
187
+ onFormCommit(controller);
161
188
  },
162
- run: () => queue(controller, "refresh"),
189
+ detachForm() {
190
+ // Only the described row's layers go away: the references keep
191
+ // answering, so nothing else has to be undone.
192
+ state.form = void 0;
193
+ routed = false;
194
+ described = false;
195
+ },
196
+ onFormCommit: () => onFormCommit(controller),
197
+ run: () => queue(controller, "probe"),
198
+ source: () => state.source(),
199
+ // The live mirror, by reference: controller modules write its fields in
200
+ // place, publish reads them off `state.live`, and every other surface
201
+ // (the commands) reads the very same answers out of it.
202
+ get live() {
203
+ return state.live;
204
+ },
205
+ selectChromePath: (path) => selectChromePath(controller, path),
163
206
  prelaunchWindowsChrome: () => prelaunchWindowsChrome(controller),
164
- onSettingsChange: () => onSettingsChange(controller)
207
+ noteRunning(entry, answers) {
208
+ mirrorRunning(controller, entry.id, answers);
209
+ },
210
+ prelaunchForConnection: () => prelaunchWindowsForConnection(controller),
211
+ dismissMigration: () => dismissMigration(controller),
212
+ dispose: () => {
213
+ // Every late answer stands down: the run chain drains on its own (the
214
+ // chain is per-instance, no shared resource left behind), and the one
215
+ // timer this instance owns is cancelled.
216
+ state.disposed = true;
217
+ cancelDiscoveryRetry(controller);
218
+ }
165
219
  };
220
+ // Form routing arrives in two steps — the entry id as soon as this fiber knows
221
+ // its own entry, then the described row once the settings service resolves —
222
+ // and the layers read live off it either way (the two flags above are what
223
+ // mark the difference between "never described" and "described before").
224
+ let routed = false;
225
+ let described = false;
226
+ // Tool-level status: browser-level failures are returned to the calling agent
227
+ // and never reach a line of their own.
228
+ registerToolCapture(controller);
229
+ // Seed the mirror before the first snapshot lands (a card that reads before
230
+ // anything ran still gets the real opening answers, never defaults).
231
+ noteSelection(controller);
232
+ return controller;
166
233
  }
167
234
  //# sourceMappingURL=controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/host/controller/controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/host/controller/controller.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,30 @@
1
1
  /**
2
2
  * Host half — the controller's live state + behavior.
3
3
  *
4
- * One controller per apply(): the composition base layer, the nested bridge, the
5
- * serialized executable runs, and the two capture paths. The public surface is
6
- * `createChromeMcpController` and its config; everything behind it is split into
7
- * concern modules:
4
+ * One controller per apply(): the live mirror the Host publishes, the serialized
5
+ * executable runs, the Windows run half, and the tool-call capture path. The
6
+ * public surface is `createChromeMcpController` (the controller object itself);
7
+ * everything behind it is split into concern modules:
8
8
  *
9
- * ./controller.ts the assembly: resolve config, build the base layer, make
10
- * the initial bridge connection, wire the public methods
9
+ * ./controller.ts the assembly: resolve config, seed the live mirror, wire
10
+ * the public methods
11
11
  * ./state.ts the live state + context every helper shares (internal)
12
- * ./notes.ts base-layer announcements (selection, stderr)
13
- * ./bridge-run.ts the bridge switches (config build, restart, flags, stderr)
12
+ * ./notes.ts live-mirror announcements (selection, stderr)
13
+ * ./connections.ts the manager seam: what answers reach the live state, and
14
+ * how a default answer change reaches live connections
14
15
  * ./runs.ts the executable run + serialization + the Windows trigger
15
16
  * ./windows-run.ts the one **Prelaunch Windows Chrome** run
16
- * ./persist.ts settings writes a run makes (seed, rows, connect flag)
17
- * ./captures.ts bridge-log + tool-call-result captures
18
- * ./commits.ts settings-commit routing (`onSettingsChange`)
17
+ * ./persist.ts the form writes a run makes (seed, rows, dismissal)
18
+ * ./captures.ts tool-call-result capture
19
+ * ./commits.ts configuration-form commit routing (`onFormCommit`)
19
20
  *
20
- * The one rule that must survive the split: read the live settings value through
21
- * `state.source()` at commit time, never capture it, and keep every base-layer
22
- * mutation in these modules — settings commits route in, never out.
21
+ * The two rules that must survive the split: read the layers through
22
+ * `state.source()` at commit time, never capture them, and route every live answer
23
+ * out through `publishLive` (./publish.ts) — configuration-form commits route in,
24
+ * never out, and the live mirror is never written by a commit path.
23
25
  */
24
26
  export { createChromeMcpController } from "./controller.js";
25
27
  export type { ChromeMcpController, ChromeMcpControllerDeps } from "./controller.js";
28
+ export type { Controller, ControllerState } from "./state.js";
29
+ export type { RunningAnswers } from "./connections.js";
26
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/host/controller/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/host/controller/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACpF,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,25 +1,27 @@
1
1
  /**
2
2
  * Host half — the controller's live state + behavior.
3
3
  *
4
- * One controller per apply(): the composition base layer, the nested bridge, the
5
- * serialized executable runs, and the two capture paths. The public surface is
6
- * `createChromeMcpController` and its config; everything behind it is split into
7
- * concern modules:
4
+ * One controller per apply(): the live mirror the Host publishes, the serialized
5
+ * executable runs, the Windows run half, and the tool-call capture path. The
6
+ * public surface is `createChromeMcpController` (the controller object itself);
7
+ * everything behind it is split into concern modules:
8
8
  *
9
- * ./controller.ts the assembly: resolve config, build the base layer, make
10
- * the initial bridge connection, wire the public methods
9
+ * ./controller.ts the assembly: resolve config, seed the live mirror, wire
10
+ * the public methods
11
11
  * ./state.ts the live state + context every helper shares (internal)
12
- * ./notes.ts base-layer announcements (selection, stderr)
13
- * ./bridge-run.ts the bridge switches (config build, restart, flags, stderr)
12
+ * ./notes.ts live-mirror announcements (selection, stderr)
13
+ * ./connections.ts the manager seam: what answers reach the live state, and
14
+ * how a default answer change reaches live connections
14
15
  * ./runs.ts the executable run + serialization + the Windows trigger
15
16
  * ./windows-run.ts the one **Prelaunch Windows Chrome** run
16
- * ./persist.ts settings writes a run makes (seed, rows, connect flag)
17
- * ./captures.ts bridge-log + tool-call-result captures
18
- * ./commits.ts settings-commit routing (`onSettingsChange`)
17
+ * ./persist.ts the form writes a run makes (seed, rows, dismissal)
18
+ * ./captures.ts tool-call-result capture
19
+ * ./commits.ts configuration-form commit routing (`onFormCommit`)
19
20
  *
20
- * The one rule that must survive the split: read the live settings value through
21
- * `state.source()` at commit time, never capture it, and keep every base-layer
22
- * mutation in these modules — settings commits route in, never out.
21
+ * The two rules that must survive the split: read the layers through
22
+ * `state.source()` at commit time, never capture them, and route every live answer
23
+ * out through `publishLive` (./publish.ts) — configuration-form commits route in,
24
+ * never out, and the live mirror is never written by a commit path.
23
25
  */
24
26
  export { createChromeMcpController } from "./controller.js";
25
27
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/host/controller/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/host/controller/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,16 +1,17 @@
1
1
  /**
2
- * Controller — base-layer announcements.
2
+ * Controller — live-mirror announcements.
3
3
  *
4
- * The two notes the base layer carries that a client can only learn from here:
5
- * the resolved selection (with the static WSL + Windows-executable state, keyed
6
- * on the *selection*, not a probe), and where the bridge console output goes.
4
+ * The two answers the card can only learn from here: the resolved selection
5
+ * (with the WSL + Windows-executable state, keyed on the *selection*, not a
6
+ * probe), and where the bridge console output goes. Both land in the live mirror
7
+ * and reach the card through one volatile commit (see ./publish.ts).
7
8
  */
8
9
  import type { BridgeStderrNotice } from "../types/index.js";
9
10
  import type { Controller } from "./state.js";
10
11
  /**
11
- * Publish the resolved selection into the base layer — with the one state the
12
- * client can only learn from here, and with the static notice that goes with it.
13
- * The Windows-executable state is keyed on the *selection*, not on any probe: a
12
+ * Publish the resolved selection into the mirror — with the one state the card
13
+ * can only learn from here, and with the static notice that goes with it. The
14
+ * Windows-executable state is keyed on the *selection*, not on any probe: a
14
15
  * Windows binary answers `--version` just fine across the interop boundary, so a
15
16
  * healthy-looking pill is exactly what a broken Windows selection looks like
16
17
  * until the first tool call fails.
@@ -19,8 +20,7 @@ export declare function noteSelection(controller: Controller): void;
19
20
  /**
20
21
  * Announce where the bridge's console output goes — one line per change of
21
22
  * state, keyed on what actually happened, so neither the "log" capture nor
22
- * a switch to console echo is silent. An unavailable redirect (no POSIX shell)
23
- * warns with the reason so the fallback is not mysterious.
23
+ * a switch to console echo is silent.
24
24
  */
25
25
  export declare function noteStderr(controller: Controller, built: BridgeStderrNotice): void;
26
26
  //# sourceMappingURL=notes.d.ts.map