@comecaramelos/dsh-chrome-mcp 0.0.1 → 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 (214) hide show
  1. package/README.md +44 -95
  2. package/assets/dsh-chrome-mcp-social.png +0 -0
  3. package/assets/icon.svg +71 -0
  4. package/assets/prelaunch-windows-chrome.html +277 -0
  5. package/lib/client.js +3005 -568
  6. package/lib/client.js.map +7 -0
  7. package/lib/host/apply.d.ts +40 -0
  8. package/lib/host/apply.d.ts.map +1 -0
  9. package/lib/host/apply.js +57 -0
  10. package/lib/host/apply.js.map +1 -0
  11. package/lib/host/bridge.d.ts +74 -0
  12. package/lib/host/bridge.d.ts.map +1 -0
  13. package/lib/host/bridge.js +168 -0
  14. package/lib/host/bridge.js.map +1 -0
  15. package/lib/host/catalog.d.ts +31 -0
  16. package/lib/host/catalog.d.ts.map +1 -0
  17. package/lib/host/catalog.js +92 -0
  18. package/lib/host/catalog.js.map +1 -0
  19. package/lib/host/commands/chrome-path.d.ts +4 -0
  20. package/lib/host/commands/chrome-path.d.ts.map +1 -0
  21. package/lib/host/commands/chrome-path.js +65 -0
  22. package/lib/host/commands/chrome-path.js.map +1 -0
  23. package/lib/host/commands/chrome-refresh.d.ts +17 -0
  24. package/lib/host/commands/chrome-refresh.d.ts.map +1 -0
  25. package/lib/host/commands/chrome-refresh.js +37 -0
  26. package/lib/host/commands/chrome-refresh.js.map +1 -0
  27. package/lib/host/commands/index.d.ts +26 -0
  28. package/lib/host/commands/index.d.ts.map +1 -0
  29. package/lib/host/commands/index.js +41 -0
  30. package/lib/host/commands/index.js.map +1 -0
  31. package/lib/host/constants.d.ts +306 -0
  32. package/lib/host/constants.d.ts.map +1 -0
  33. package/lib/host/constants.js +319 -0
  34. package/lib/host/constants.js.map +1 -0
  35. package/lib/host/controller/_trace.d.ts +3 -0
  36. package/lib/host/controller/_trace.d.ts.map +1 -0
  37. package/lib/host/controller/_trace.js +14 -0
  38. package/lib/host/controller/_trace.js.map +1 -0
  39. package/lib/host/controller/bridge-run.d.ts +40 -0
  40. package/lib/host/controller/bridge-run.d.ts.map +1 -0
  41. package/lib/host/controller/bridge-run.js +85 -0
  42. package/lib/host/controller/bridge-run.js.map +1 -0
  43. package/lib/host/controller/captures.d.ts +15 -0
  44. package/lib/host/controller/captures.d.ts.map +1 -0
  45. package/lib/host/controller/captures.js +85 -0
  46. package/lib/host/controller/captures.js.map +1 -0
  47. package/lib/host/controller/commits.d.ts +4 -0
  48. package/lib/host/controller/commits.d.ts.map +1 -0
  49. package/lib/host/controller/commits.js +131 -0
  50. package/lib/host/controller/commits.js.map +1 -0
  51. package/lib/host/controller/connections.d.ts +38 -0
  52. package/lib/host/controller/connections.d.ts.map +1 -0
  53. package/lib/host/controller/connections.js +71 -0
  54. package/lib/host/controller/connections.js.map +1 -0
  55. package/lib/host/controller/controller.d.ts +35 -0
  56. package/lib/host/controller/controller.d.ts.map +1 -0
  57. package/lib/host/controller/controller.js +234 -0
  58. package/lib/host/controller/controller.js.map +1 -0
  59. package/lib/host/controller/index.d.ts +30 -0
  60. package/lib/host/controller/index.d.ts.map +1 -0
  61. package/lib/host/controller/index.js +27 -0
  62. package/lib/host/controller/index.js.map +1 -0
  63. package/lib/host/controller/notes.d.ts +26 -0
  64. package/lib/host/controller/notes.d.ts.map +1 -0
  65. package/lib/host/controller/notes.js +44 -0
  66. package/lib/host/controller/notes.js.map +1 -0
  67. package/lib/host/controller/persist.d.ts +16 -0
  68. package/lib/host/controller/persist.d.ts.map +1 -0
  69. package/lib/host/controller/persist.js +98 -0
  70. package/lib/host/controller/persist.js.map +1 -0
  71. package/lib/host/controller/publish.d.ts +4 -0
  72. package/lib/host/controller/publish.d.ts.map +1 -0
  73. package/lib/host/controller/publish.js +56 -0
  74. package/lib/host/controller/publish.js.map +1 -0
  75. package/lib/host/controller/runs.d.ts +80 -0
  76. package/lib/host/controller/runs.d.ts.map +1 -0
  77. package/lib/host/controller/runs.js +394 -0
  78. package/lib/host/controller/runs.js.map +1 -0
  79. package/lib/host/controller/state.d.ts +172 -0
  80. package/lib/host/controller/state.d.ts.map +1 -0
  81. package/lib/host/controller/state.js +2 -0
  82. package/lib/host/controller/state.js.map +1 -0
  83. package/lib/host/controller/windows-run.d.ts +17 -0
  84. package/lib/host/controller/windows-run.d.ts.map +1 -0
  85. package/lib/host/controller/windows-run.js +109 -0
  86. package/lib/host/controller/windows-run.js.map +1 -0
  87. package/lib/host/discovery/candidates.d.ts +47 -0
  88. package/lib/host/discovery/candidates.d.ts.map +1 -0
  89. package/lib/host/discovery/candidates.js +68 -0
  90. package/lib/host/discovery/candidates.js.map +1 -0
  91. package/lib/host/discovery/index.d.ts +19 -0
  92. package/lib/host/discovery/index.d.ts.map +1 -0
  93. package/lib/host/discovery/index.js +19 -0
  94. package/lib/host/discovery/index.js.map +1 -0
  95. package/lib/host/discovery/probe.d.ts +29 -0
  96. package/lib/host/discovery/probe.d.ts.map +1 -0
  97. package/lib/host/discovery/probe.js +155 -0
  98. package/lib/host/discovery/probe.js.map +1 -0
  99. package/lib/host/discovery/scan.d.ts +72 -0
  100. package/lib/host/discovery/scan.d.ts.map +1 -0
  101. package/lib/host/discovery/scan.js +195 -0
  102. package/lib/host/discovery/scan.js.map +1 -0
  103. package/lib/host/flags.d.ts +65 -0
  104. package/lib/host/flags.d.ts.map +1 -0
  105. package/lib/host/flags.js +186 -0
  106. package/lib/host/flags.js.map +1 -0
  107. package/lib/host/kind.d.ts +45 -0
  108. package/lib/host/kind.d.ts.map +1 -0
  109. package/lib/host/kind.js +251 -0
  110. package/lib/host/kind.js.map +1 -0
  111. package/lib/host/manager.d.ts +21 -0
  112. package/lib/host/manager.d.ts.map +1 -0
  113. package/lib/host/manager.js +113 -0
  114. package/lib/host/manager.js.map +1 -0
  115. package/lib/host/migration.d.ts +26 -0
  116. package/lib/host/migration.d.ts.map +1 -0
  117. package/lib/host/migration.js +127 -0
  118. package/lib/host/migration.js.map +1 -0
  119. package/lib/host/platform.d.ts +38 -0
  120. package/lib/host/platform.d.ts.map +1 -0
  121. package/lib/host/platform.js +64 -0
  122. package/lib/host/platform.js.map +1 -0
  123. package/lib/host/plugin-meta.d.ts +21 -0
  124. package/lib/host/plugin-meta.d.ts.map +1 -0
  125. package/lib/host/plugin-meta.js +21 -0
  126. package/lib/host/plugin-meta.js.map +1 -0
  127. package/lib/host/schema.d.ts +361 -0
  128. package/lib/host/schema.d.ts.map +1 -0
  129. package/lib/host/schema.js +196 -0
  130. package/lib/host/schema.js.map +1 -0
  131. package/lib/host/settings.d.ts +28 -0
  132. package/lib/host/settings.d.ts.map +1 -0
  133. package/lib/host/settings.js +91 -0
  134. package/lib/host/settings.js.map +1 -0
  135. package/lib/host/status.d.ts +25 -0
  136. package/lib/host/status.d.ts.map +1 -0
  137. package/lib/host/status.js +45 -0
  138. package/lib/host/status.js.map +1 -0
  139. package/lib/host/tool.d.ts +65 -0
  140. package/lib/host/tool.d.ts.map +1 -0
  141. package/lib/host/tool.js +52 -0
  142. package/lib/host/tool.js.map +1 -0
  143. package/lib/host/types/config.d.ts +101 -0
  144. package/lib/host/types/config.d.ts.map +1 -0
  145. package/lib/host/types/config.js +2 -0
  146. package/lib/host/types/config.js.map +1 -0
  147. package/lib/host/types/executable.d.ts +35 -0
  148. package/lib/host/types/executable.d.ts.map +1 -0
  149. package/lib/host/types/executable.js +9 -0
  150. package/lib/host/types/executable.js.map +1 -0
  151. package/lib/host/types/index.d.ts +24 -0
  152. package/lib/host/types/index.d.ts.map +1 -0
  153. package/lib/host/types/index.js +2 -0
  154. package/lib/host/types/index.js.map +1 -0
  155. package/lib/host/types/plugin.d.ts +38 -0
  156. package/lib/host/types/plugin.d.ts.map +1 -0
  157. package/lib/host/types/plugin.js +10 -0
  158. package/lib/host/types/plugin.js.map +1 -0
  159. package/lib/host/types/services.d.ts +26 -0
  160. package/lib/host/types/services.d.ts.map +1 -0
  161. package/lib/host/types/services.js +9 -0
  162. package/lib/host/types/services.js.map +1 -0
  163. package/lib/host/types/settings.d.ts +180 -0
  164. package/lib/host/types/settings.d.ts.map +1 -0
  165. package/lib/host/types/settings.js +2 -0
  166. package/lib/host/types/settings.js.map +1 -0
  167. package/lib/host/types/stderr.d.ts +51 -0
  168. package/lib/host/types/stderr.d.ts.map +1 -0
  169. package/lib/host/types/stderr.js +9 -0
  170. package/lib/host/types/stderr.js.map +1 -0
  171. package/lib/host/types/windows.d.ts +39 -0
  172. package/lib/host/types/windows.d.ts.map +1 -0
  173. package/lib/host/types/windows.js +9 -0
  174. package/lib/host/types/windows.js.map +1 -0
  175. package/lib/host/values.d.ts +204 -0
  176. package/lib/host/values.d.ts.map +1 -0
  177. package/lib/host/values.js +404 -0
  178. package/lib/host/values.js.map +1 -0
  179. package/lib/host/windows/connect-flags.d.ts +27 -0
  180. package/lib/host/windows/connect-flags.d.ts.map +1 -0
  181. package/lib/host/windows/connect-flags.js +97 -0
  182. package/lib/host/windows/connect-flags.js.map +1 -0
  183. package/lib/host/windows/index.d.ts +31 -0
  184. package/lib/host/windows/index.d.ts.map +1 -0
  185. package/lib/host/windows/index.js +30 -0
  186. package/lib/host/windows/index.js.map +1 -0
  187. package/lib/host/windows/landing.d.ts +47 -0
  188. package/lib/host/windows/landing.d.ts.map +1 -0
  189. package/lib/host/windows/landing.js +174 -0
  190. package/lib/host/windows/landing.js.map +1 -0
  191. package/lib/host/windows/link.d.ts +11 -0
  192. package/lib/host/windows/link.d.ts.map +1 -0
  193. package/lib/host/windows/link.js +52 -0
  194. package/lib/host/windows/link.js.map +1 -0
  195. package/lib/host/windows/paths.d.ts +64 -0
  196. package/lib/host/windows/paths.d.ts.map +1 -0
  197. package/lib/host/windows/paths.js +148 -0
  198. package/lib/host/windows/paths.js.map +1 -0
  199. package/lib/host/windows/run.d.ts +74 -0
  200. package/lib/host/windows/run.d.ts.map +1 -0
  201. package/lib/host/windows/run.js +211 -0
  202. package/lib/host/windows/run.js.map +1 -0
  203. package/lib/host/windows/spawn.d.ts +22 -0
  204. package/lib/host/windows/spawn.d.ts.map +1 -0
  205. package/lib/host/windows/spawn.js +73 -0
  206. package/lib/host/windows/spawn.js.map +1 -0
  207. package/lib/index.d.ts +102 -0
  208. package/lib/index.d.ts.map +1 -0
  209. package/lib/index.js +102 -636
  210. package/lib/index.js.map +1 -0
  211. package/locale/en.json +6 -0
  212. package/locale/zh.json +6 -0
  213. package/package.json +57 -14
  214. package/cordis.patch.yml +0 -5
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Controller — the executable run, its serialization, and the Windows trigger.
3
+ *
4
+ * Every executable action goes through one **run**: probe the candidate list the
5
+ * saved rows + row config + selection carry, publish the per-path answers, and
6
+ * merge what was found back into the saved rows (keeping the names the user
7
+ * gave them). When nothing is configured at all, the first runnable entry is
8
+ * seeded. A `probe` is the follow-up probe of the selection that answers the
9
+ * version line the card shows; the Windows Chrome run shares this same
10
+ * one-run-at-a-time chain.
11
+ *
12
+ * Since the component model there is no bridge of this row's own to restart:
13
+ * an executable or flag change changes what a future `resolve` would answer,
14
+ * and what is running today keeps running until the manager's pool says
15
+ * otherwise — so the drift paths re-mirror the default and hand the live
16
+ * connections that follow it back to the pool (./connections.ts).
17
+ */
18
+ import { AsyncResource } from "node:async_hooks";
19
+ import { entryIds, mergeEntries } from "../catalog.js";
20
+ import { DISCOVERY_RETRY_DELAY_MS, DISCOVERY_RETRY_MAX, ERROR_CAP, KIND_FIELDS, KIND_ID_WINDOWS } from "../constants.js";
21
+ import { checkChrome, chromeExecutableCandidates, scanChromeExecutables } from "../discovery/index.js";
22
+ import { flagsSkipCheck, flagsSkipProbe } from "../flags.js";
23
+ import { firstLine, isChromeMissing } from "../status.js";
24
+ import { windowsChromeUrl } from "../windows/index.js";
25
+ import { readDroppedExecutables, readPersistedCustomPaths, readSavedExecutables, resolveSelection } from "../values.js";
26
+ import { invalidateOwnedForField } from "./connections.js";
27
+ import { noteSelection } from "./notes.js";
28
+ import { persistChromePath, persistDroppedExecutables, persistExecutables } from "./persist.js";
29
+ import { publishLive } from "./publish.js";
30
+ import { prelaunchWindowsForConnection, runWindowsChrome } from "./windows-run.js";
31
+ /**
32
+ * The runs answer from a neutral async context, never from the one that
33
+ * scheduled them. A form commit is a config **write** — and the commit handler
34
+ * runs synchronously inside the HMR write transaction it opened. A run
35
+ * scheduled from that handler inherits the transaction's async-local store
36
+ * through the promise continuation, so every follow-up config write the run
37
+ * answers — the seeded `chromePath`, the merged executable rows, the
38
+ * connect-mode flag — reads as a *nested* transaction, which HMR refuses
39
+ * outright ("HMR transactions cannot be nested", measured live 2026-10-12):
40
+ * the run settles, the mirror says `connected`, and the write-back silently
41
+ * never lands. This resource carries no async context of its own, so binding
42
+ * the run body to it starts the whole chain clean; the same write queues
43
+ * normally behind the transaction that is no longer open. (The option that drops
44
+ * the context predates the typed surface of `AsyncResourceOptions`.)
45
+ */
46
+ const contextlessOptions = { keepAsyncContext: false };
47
+ const runContext = new AsyncResource("dsh-chrome-mcp run", contextlessOptions);
48
+ /** Element-wise equality of two saved-row lists (order is the dropdown order). */
49
+ export function sameEntries(a, b) {
50
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)
51
+ return false;
52
+ return a.every((entry, index) => entry.id === b[index].id && entry.name === b[index].name);
53
+ }
54
+ /**
55
+ * Fold the legacy hand-typed MRU into the rows, exactly once. It is the same list
56
+ * the older card used to write, so reading it never duplicates a row the card
57
+ * already saved: the merge keeps stored rows and only appends ids that are
58
+ * missing, and the result lands in the persisted rows instead of staying
59
+ * readable forever as a second source.
60
+ */
61
+ export function mergeLegacyPaths(controller, skip) {
62
+ const { state } = controller;
63
+ if (state.legacyPathsMerged)
64
+ return state.runningExecutables;
65
+ state.legacyPathsMerged = true;
66
+ const legacy = readPersistedCustomPaths(state.source());
67
+ if (legacy.length === 0)
68
+ return state.runningExecutables;
69
+ const merged = mergeEntries(state.runningExecutables, skip === void 0 ? legacy : legacy.filter((id) => !skip.has(id)));
70
+ if (merged.changed) {
71
+ state.runningExecutables = merged.entries;
72
+ void persistExecutables(controller, merged.entries);
73
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): folded ${String(legacy.length)} saved path(s) from the legacy chromeCustomPaths list into the executable rows`);
74
+ }
75
+ return state.runningExecutables;
76
+ }
77
+ /**
78
+ * One executable run. Probe every candidate the row config and the saved rows
79
+ * carry (plus the selection — the same path may appear as a row), publish what
80
+ * answered as per-path status, and merge what was found into the saved rows,
81
+ * keeping the names their user gave them. When nothing is configured at all
82
+ * (neither layer carries a path) the first runnable entry is **seeded**: written
83
+ * into the persisted `chromePath` once, so what the picker shows is what the
84
+ * bridge runs. A selection that is already fixed is never re-resolved, however
85
+ * broken.
86
+ * @returns the per-path statuses the run answered with.
87
+ */
88
+ export async function runExecutableDiscovery(controller) {
89
+ const { state } = controller;
90
+ const layers = state.source();
91
+ // Rows are user-authored; re-normalize on every read (the client writes them
92
+ // in one shot, so the shape it hands may be anything).
93
+ const stored = readSavedExecutables(layers);
94
+ // An id the stored list has lost since the last run rode the run that is
95
+ // reading it now — and a found path re-folds into the rows on every merge
96
+ // step, so a deleted row would stand straight back up behind its own
97
+ // deletion (measured live 2026-10-12: the (x86) Windows-executable row read
98
+ // as a delete that never landed). What stands dropped lives in
99
+ // `droppedExecutables` and no merge step folds it back; an id the list
100
+ // carries again clears its record.
101
+ const storedIds = new Set(entryIds(stored));
102
+ const deleted = readDroppedExecutables(layers);
103
+ const skipIds = new Set(deleted);
104
+ for (const id of entryIds(state.runningExecutables)) {
105
+ if (!storedIds.has(id))
106
+ skipIds.add(id);
107
+ }
108
+ for (const id of deleted) {
109
+ if (storedIds.has(id))
110
+ skipIds.delete(id);
111
+ }
112
+ if (skipIds.size !== deleted.length || !deleted.every((id) => skipIds.has(id))) {
113
+ void persistDroppedExecutables(controller, [...skipIds]);
114
+ }
115
+ const storedChanged = !sameEntries(stored, state.runningExecutables);
116
+ state.runningExecutables = storedChanged ? stored : mergeLegacyPaths(controller, skipIds);
117
+ const savedIds = entryIds(state.runningExecutables);
118
+ // What the profile configures, what this host carries (the Windows-side
119
+ // executables a WSL host reaches through the interop mount — offered, never
120
+ // probed), what the rows saved, and what the bridge runs.
121
+ const candidates = chromeExecutableCandidates(controller.config, savedIds, state.runningChromePath, controller.windowsExecutables());
122
+ let statuses = [];
123
+ try {
124
+ statuses = await scanChromeExecutables(candidates, controller.blockedForPlatform);
125
+ }
126
+ catch (error) {
127
+ controller.ctx.logger.warn(`dsh-chrome-mcp(${controller.config.serverName}): executable run failed: ${String(error)}`);
128
+ }
129
+ state.live.executableStatus = statuses;
130
+ // A found path that is not a row yet becomes one, nameless; a row the user
131
+ // named keeps that name. A path that vanished is dropped by the scan and so
132
+ // stops being offered — the reference's "Fetch executables" rule. A path the
133
+ // user dropped answers too (a located Windows executable keeps answering
134
+ // forever) and must not be folded back.
135
+ const merged = mergeEntries(state.runningExecutables, statuses.map((status) => status.path).filter((path) => !skipIds.has(path)));
136
+ if (merged.changed) {
137
+ state.runningExecutables = merged.entries;
138
+ void persistExecutables(controller, merged.entries);
139
+ }
140
+ if (state.runningChromePath === "") {
141
+ const seeded = statuses.find((status) => status.version !== "" && status.error === "");
142
+ if (seeded !== void 0 && !flagsSkipProbe(state.runningFlags)) {
143
+ // Seeding is a selection change like any other: it follows the same
144
+ // drift path a pick takes, otherwise the card would claim a path no
145
+ // answer launches with.
146
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): no executable configured — seeding chromePath = ${seeded.path} (found by scan)`);
147
+ state.seededPath = seeded.path;
148
+ void persistChromePath(controller, seeded.path);
149
+ // Already inside this run: the status list above already carries the
150
+ // seeded path's own answer, so no follow-up run.
151
+ applyChromePath(controller, seeded.path, "selected", false);
152
+ }
153
+ else if (candidates.length > 0 && !flagsSkipProbe(state.runningFlags) && statuses.every((status) => status.error !== "" || status.version === "")) {
154
+ // Nothing runnable at all: the known executable-missing state. A
155
+ // candidate that answered a note instead of a version says why —
156
+ // the one case is the Windows executable a WSL host cannot launch
157
+ // but drives through the **Prelaunch Windows Chrome** run — so the
158
+ // line names what to run instead of leaving a bare "not found".
159
+ const noted = statuses.find((status) => status.note !== "");
160
+ const detail = noted === void 0
161
+ ? `no executable detected (checked: ${candidates.join(", ")})`
162
+ : `no executable detected for this host (checked: ${candidates.join(", ")}); ${firstLine(noted.note)}`;
163
+ // The official troubleshooting advice for this state on a Linux
164
+ // host (docs/troubleshooting.md): nothing local answered, and the
165
+ // candidate list only knows where a `stable` install of this kernel
166
+ // lives — the line says what to do about it instead of leaving a
167
+ // bare "not found". On a WSL host the Windows side joins the answer
168
+ // as the **run**, never a launch: a Windows `chrome.exe` cannot be
169
+ // launched from WSL (see AGENTS.md, which is why the run exists).
170
+ const advice = noted === void 0 && controller.linuxHost
171
+ ? controller.wslHost
172
+ ? "; install Google Chrome inside the Linux environment, or run Prelaunch Windows Chrome to drive the Windows side (connect mode)"
173
+ : "; install Google Chrome inside the Linux environment (chrome-devtools-mcp never downloads one)"
174
+ : "";
175
+ state.live.lastError = firstLine(`Chrome executable not found: ${detail}${advice}`, ERROR_CAP + advice.length);
176
+ state.live.chromeMissing = isChromeMissing(state.live.lastError);
177
+ }
178
+ }
179
+ noteSelection(controller);
180
+ return statuses;
181
+ }
182
+ /**
183
+ * The probe of the *selection* — the one run that answers the version line the
184
+ * card shows under the pill. Nothing probed (no selection, or a connect-mode
185
+ * flag) must not clear anything: upstream starts the browser lazily, so silence
186
+ * is not health.
187
+ */
188
+ export async function probeSelection(controller) {
189
+ const { state } = controller;
190
+ // Connect mode launches nothing locally, so there is no local executable to
191
+ // answer for: the card mutes the pill and shows no version line for a probe
192
+ // the host cannot run.
193
+ if (flagsSkipCheck(state.runningFlags)) {
194
+ state.live.chromeVersion = "";
195
+ publishLive(controller);
196
+ return "";
197
+ }
198
+ if (state.runningChromePath === "") {
199
+ state.live.chromeVersion = "";
200
+ publishLive(controller);
201
+ return "";
202
+ }
203
+ try {
204
+ const version = await checkChrome({ ...controller.config, extraFlags: state.runningFlags, chromePath: state.runningChromePath }, state.runningFlags, controller.blockedForPlatform);
205
+ state.live.chromeVersion = version;
206
+ if (version !== "") {
207
+ state.live.lastError = "";
208
+ state.live.chromeMissing = false;
209
+ }
210
+ publishLive(controller);
211
+ return version;
212
+ }
213
+ catch (error) {
214
+ state.live.lastError = firstLine(error instanceof Error ? error.message : String(error));
215
+ // A failed probe says nothing about the version: keep no stale answer
216
+ // behind the error.
217
+ state.live.chromeVersion = "";
218
+ state.live.chromeMissing = isChromeMissing(state.live.lastError);
219
+ publishLive(controller);
220
+ controller.ctx.logger.warn(`dsh-chrome-mcp(${controller.config.serverName}): executable probe failed: ${state.live.lastError}`);
221
+ return "";
222
+ }
223
+ }
224
+ /**
225
+ * Write one executable selection through the Host write-back channel — the same
226
+ * persisted `chromePath` field every other surface reads — and re-fire the run
227
+ * behind it, the way the card's own selection commit does: a changed selection
228
+ * shifts the default answers (connections follow, the run re-runs), an
229
+ * unchanged write just re-probes. This is the command-side mirror of the
230
+ * picker — pill, command and catalog read and write one field — so a headless
231
+ * selection lands exactly where a GUI pick would.
232
+ */
233
+ export function selectChromePath(controller, path) {
234
+ return persistChromePath(controller, path).then(() => {
235
+ const { state } = controller;
236
+ // Layers read *after* the write: what the user layer answers is the
237
+ // written path — or, on a cleared write ("" = fall back to the row
238
+ // config), whatever the row config carries under it.
239
+ const selection = resolveSelection(state.source());
240
+ const nextChromePath = selection.path;
241
+ const nextSource = nextChromePath === "" ? "" : selection.source !== "" ? selection.source : "selected";
242
+ if (nextChromePath !== state.runningChromePath || nextSource !== state.runningChromeSource)
243
+ applyChromePath(controller, nextChromePath, nextSource);
244
+ else
245
+ queue(controller, "probe");
246
+ });
247
+ }
248
+ /**
249
+ * Carry a different executable into the live answers — the argv tail carries
250
+ * `--executablePath=<path>`, so unlike a flags edit this one is what the card's
251
+ * pill claims is running. What lives stands on is not restarted here: a
252
+ * connection that follows the row's default is handed back to the pool for a
253
+ * re-resolve, and one that picked its own executable was never following it.
254
+ * `rerun` schedules the scan+probe that follows a selection change; a caller
255
+ * that is already inside that run (the seeding branch above) passes `false`.
256
+ */
257
+ export function applyChromePath(controller, path, nextSource, rerun = true) {
258
+ const { state } = controller;
259
+ state.runningChromePath = path;
260
+ state.runningChromeSource = nextSource;
261
+ state.live.runningNote = "";
262
+ noteSelection(controller);
263
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): executable → "${path || "(none)"}" (the default answers shift with it)`);
264
+ invalidateOwnedForField(controller, KIND_FIELDS.executable);
265
+ // A different executable reads a different machine: refresh the list and
266
+ // probe what is now selected, so the pill's version is the new one's.
267
+ if (rerun)
268
+ queue(controller, "probe");
269
+ }
270
+ /**
271
+ * The bounded retry of one FAILED executable run.
272
+ *
273
+ * The failure this answers is not "Chrome is not installed" — that answer is a
274
+ * settled result and re-probing it forever would just be churn. It is the
275
+ * host that is not ready *yet*: on a WSL boot the Windows executables arrive
276
+ * through the interop mount, and the first run can fire seconds before that
277
+ * mount answers, so what the run states — `chromeMissing`, the known
278
+ * executable-missing state — reads "no found" for a machine that is about to
279
+ * answer. Today nothing re-fires: the card states that answer until someone
280
+ * presses **Fetch** again. So a run that settles standing failed arms exactly
281
+ * one retry behind the delay, capped (`DISCOVERY_RETRY_MAX` retries per run
282
+ * chain, reset the moment a run stops failing), and cancelled with the
283
+ * instance.
284
+ *
285
+ * The rule that decides where the retry sits is the persistence of the known
286
+ * error: the retry never touches `lastError`/`chromeMissing` — it *re-runs the
287
+ * same run*, whose own answers already follow the evidence rule (the run clears
288
+ * those fields only through a probe that answered a version). So the retry
289
+ * cannot clobber what the user is already being told: either the later run finds
290
+ * the executable (its probe answers a version, which is exactly the evidence
291
+ * that clears the state), or it does not (the same answer re-states, still
292
+ * standing). Nothing else distinguishes them — which is why arming the retry is
293
+ * safe and why it arms only while the state stands.
294
+ */
295
+ function noteRunFailure(controller, statuses) {
296
+ const { state } = controller;
297
+ // Only a run that settled standing in the known executable-missing state is
298
+ // failed. And of those, the candidates that answered a platform *note* say
299
+ // why no run on this host will ever launch them (the one case is the Windows
300
+ // executable a WSL host drives through **Prelaunch Windows Chrome**) — that
301
+ // is a settled answer, not a host not ready yet, so a retry would answer the
302
+ // same note forever and is not armed.
303
+ const noteOnly = statuses.length > 0 && statuses.every((status) => status.note !== "");
304
+ if (state.live.chromeMissing !== true || noteOnly) {
305
+ state.retriesPending = 0;
306
+ return;
307
+ }
308
+ if (state.disposed)
309
+ return;
310
+ if (state.retryTimer !== void 0)
311
+ return;
312
+ if (state.retriesPending >= DISCOVERY_RETRY_MAX)
313
+ return;
314
+ state.retriesPending += 1;
315
+ state.retryTimer = setTimeout(() => {
316
+ state.retryTimer = void 0;
317
+ // Only while the failure still stands: an instance whose later run found
318
+ // the executable has nothing left to retry.
319
+ if (state.disposed || state.live.chromeMissing !== true)
320
+ return;
321
+ void queue(controller, "probe");
322
+ }, DISCOVERY_RETRY_DELAY_MS);
323
+ }
324
+ /** Cancel the pending bounded retry — what the instance's dispose calls. */
325
+ export function cancelDiscoveryRetry(controller) {
326
+ const { state } = controller;
327
+ if (state.retryTimer !== void 0) {
328
+ clearTimeout(state.retryTimer);
329
+ state.retryTimer = void 0;
330
+ }
331
+ }
332
+ /**
333
+ * Serialize one unit of work: a rows-only refresh, a run that also re-probes
334
+ * what is selected, or the Windows Chrome launch. Windows runs share this chain
335
+ * because the invariant is "one run at a time" — nothing about it interacts with
336
+ * the local probe. The body answers from a neutral async context (see
337
+ * `runContext`): a run scheduled from a form commit must not carry that
338
+ * commit's write transaction, or every write the run answers would be refused
339
+ * as a nested transaction.
340
+ */
341
+ export function queue(controller, kind) {
342
+ const { state } = controller;
343
+ state.runs = state.runs
344
+ .then(runContext.bind(async () => {
345
+ if (kind === "windows") {
346
+ await runWindowsChrome(controller);
347
+ }
348
+ else {
349
+ const statuses = await runExecutableDiscovery(controller);
350
+ if (kind === "probe")
351
+ await probeSelection(controller);
352
+ // A run that settled standing failed arms one bounded retry; a
353
+ // run that no longer stands failed resets the retry counter.
354
+ noteRunFailure(controller, statuses);
355
+ }
356
+ state.live.executableDiscoveryRevision += 1;
357
+ publishLive(controller);
358
+ }))
359
+ .catch(() => { });
360
+ return state.runs;
361
+ }
362
+ /**
363
+ * One Windows Chrome run on demand: queued on the same chain as the button (one
364
+ * run at a time), resolved once it settled. The answer is the live mirror read
365
+ * after the run — the tool surface says what `windowsChromeStatus` says, never
366
+ * more than the run answered.
367
+ *
368
+ * With the manager mounted this is also the surface that keeps the live
369
+ * `chrome-windows` connections honest: a run that connected while such a
370
+ * connection stands is a reason to answer that connection again (the run is
371
+ * idempotent — the live port rides into `currentFlags` — so re-answering is not
372
+ * a second browser), and a run that connected without one is said to be worth
373
+ * one.
374
+ */
375
+ export async function prelaunchWindowsChrome(controller) {
376
+ const { state } = controller;
377
+ await prelaunchWindowsForConnection(controller);
378
+ const status = state.live.windowsChromeStatus;
379
+ if (status.state === "connected" && status.port > 0) {
380
+ const url = windowsChromeUrl(status.port);
381
+ if (state.connections !== void 0) {
382
+ const windowsEntries = state.connections.entries().filter((entry) => entry.kind === KIND_ID_WINDOWS);
383
+ if (windowsEntries.length > 0)
384
+ return `Windows Chrome connected at ${url} — the manager's Windows Chrome connections stand live against it.`;
385
+ return `Windows Chrome connected at ${url}. No Windows Chrome connection exists yet — add one under the "Windows Chrome (WSL debug port)" kind, or use the Chrome connection kind with a "--browserUrl=${url}" flag.`;
386
+ }
387
+ return `Windows Chrome connected at ${url}. Without the MCP manager there is no connection to drive it — install the MCP manager bundle.`;
388
+ }
389
+ if (status.state === "not-applicable") {
390
+ return "This host is not a WSL instance: there is no Windows-side browser here to drive.";
391
+ }
392
+ return `Windows Chrome did not connect (${status.state}): ${status.error}`;
393
+ }
394
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../../src/host/controller/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Controller internals — the live state + the context every controller method
3
+ * reads.
4
+ *
5
+ * The public half (`createChromeMcpController`, `ChromeMcpController`,
6
+ * `ChromeMcpControllerDeps`) lives in ./controller.ts; the behavior it wires
7
+ * together is split across the sibling modules here (`notes`, `connections`,
8
+ * `runs`, `windows-run`, `persist`, `captures`, `commits`). This file names the
9
+ * state those helpers share — every live answer targets `state.live` and reaches
10
+ * the card through `publishLive`, every layer read goes through `state.source`,
11
+ * and the immutable context pieces a method needs to act on (the row config, the
12
+ * WSL answer, the injected Windows run, the manager's connection service) sit
13
+ * alongside it. Nothing here is part of the public surface.
14
+ */
15
+ import type { BridgeStderrMode, ChromeMcpConfig, ChromeExecutableEntry, ConfigLayers, ConfigLiveFields, ChromeMcpForm, EffectiveChromeSource, PluginContext, WindowsChromeRun } from "../types/index.js";
16
+ import type { WindowsChromeRunOptions } from "../windows/index.js";
17
+ import type { LiveMirror } from "@comecaramelos/dsh-ancesters/host";
18
+ import type { McpConnectionsService } from "@comecaramelos/dsh-mcp-manager/api";
19
+ import type { RunningAnswers } from "./connections.js";
20
+ /** The live state one controller instance owns and mutates. */
21
+ export interface ControllerState {
22
+ /** The live mirror — what every Host answer carries, published through the
23
+ * volatile references on every change batch, never persisted. */
24
+ live: ConfigLiveFields;
25
+ /** The configuration form once it is attached (undefined until the settings
26
+ * service resolves and the row's entry id is known). */
27
+ form: ChromeMcpForm | undefined;
28
+ /** Read the form's layers (the user layer over the row config). Swapped when
29
+ * the form attaches; before that the references answer alone. */
30
+ source: () => ConfigLayers;
31
+ /** Flags the default answers run with — what a connection with no own
32
+ * `extra` answer is answered with. Mirrored from the last resolve, so what
33
+ * the machine page states is what is running, not what was last configured. */
34
+ runningFlags: string[];
35
+ /** Effective console-output mode of the default answer ("log"/"console"). */
36
+ runningStderrMode: BridgeStderrMode;
37
+ /** Executable the default answer launches with. */
38
+ runningChromePath: string;
39
+ /** Where that executable came from. */
40
+ runningChromeSource: EffectiveChromeSource;
41
+ /** The saved rows the last commit served, already normalized. */
42
+ runningExecutables: ChromeExecutableEntry[];
43
+ /** Last emitted stderr notice key (keeps the announce silent across churn). */
44
+ stderrNotice: string;
45
+ /** Last observed `refreshExecutablesNonce` (undefined until first commit). */
46
+ lastRefreshNonce: number | undefined;
47
+ /** Last observed `openWindowsChromeNonce` (undefined until first commit). */
48
+ lastWindowsNonce: number | undefined;
49
+ /** The executable this host seeded on the first run ("" = nothing). */
50
+ seededPath: string;
51
+ /** Whether the user layer has ever carried a path. */
52
+ seenUserSelection: boolean;
53
+ /** Serializes runs so rapid actions never interleave. */
54
+ runs: Promise<unknown>;
55
+ /**
56
+ * One bounded retry of a FAILED executable run. The run chain answers once
57
+ * per queue and never re-tries on its own — a host that answers empty (the
58
+ * shape a WSL boot takes while the interop mount is not served yet) would
59
+ * read "not found" until someone pressed Fetch. So a failing run arms
60
+ * **one** retry behind `DISCOVERY_RETRY_DELAY_MS`, capped across the
61
+ * instance at `DISCOVERY_RETRY_MAX`, and any run that no longer stands
62
+ * failed resets the count. Cancelled when the instance is disposed.
63
+ */
64
+ retryTimer: NodeJS.Timeout | undefined;
65
+ /** Consecutive scheduled retries after failed runs; reset on a non-failed
66
+ * run. */
67
+ retriesPending: number;
68
+ /** Set once this instance is disposed: a late retry answer must not fire
69
+ * runs for an instance that no longer exists. */
70
+ disposed: boolean;
71
+ /** Whether the WSL + Windows-executable warning has been logged already. */
72
+ wslNoticeShown: boolean;
73
+ /** Whether the workspace `.chrome` view "kept" notice has been logged. */
74
+ profileLinkKeptShown: boolean;
75
+ /** Whether the legacy hand-typed MRU has been folded into the rows already. */
76
+ legacyPathsMerged: boolean;
77
+ /** Whether the row config's legacy `--executablePath` fold has been announced
78
+ * already (one warn line, however often the layers churn). */
79
+ legacyPinAnnounced: boolean;
80
+ /** The live mirror (ancestros' `createLiveMirror`), stood up on the first
81
+ * publish. */
82
+ mirror: LiveMirror | undefined;
83
+ /** Set while one coalesced "kinds changed" notice is already queued. */
84
+ kindsNotifyQueued: boolean;
85
+ /** The manager's `mcpConnections` service while the manager runs it (see
86
+ * ../manager.ts). Undefined when no manager stands behind this row — the
87
+ * component then answers the row's own page and starts nothing. */
88
+ connections: McpConnectionsService | undefined;
89
+ /** Says "what a picker would answer just moved" (./../manager.ts installs
90
+ * the real half); a no-op until then. */
91
+ notifyKindsChanged: () => void;
92
+ }
93
+ /** Everything a controller method needs: the immutable context + the state.
94
+ * `ChromeMcpController` is this same type — the public surface is the object
95
+ * itself, and every consumer (the form, the commands, the kinds) works through
96
+ * one and the same instance. */
97
+ export interface Controller {
98
+ ctx: PluginContext;
99
+ /** The config `apply` validated. Every `.volatile()` field here is a
100
+ * reference, not a value — read them through `readConfigField`. */
101
+ config: ChromeMcpConfig;
102
+ /** True on a WSL host (where the Windows run is the only working path). */
103
+ wslHost: boolean;
104
+ /** True on a Linux host. The candidate list models the stable-channel
105
+ * installs a Linux host carries, so the executable-missing answer's advice
106
+ * keys on this (see `runs.ts`); WSL is the case with the Windows-side
107
+ * alternative next to it. */
108
+ linuxHost: boolean;
109
+ /** A path this host must never exec (a Windows binary under WSL). */
110
+ blockedForPlatform: (candidate: string) => string;
111
+ /** The `DSH_CHROME_MCP_FLAGS` answer from the launch environment (anything
112
+ * the caller did not supply is "no answer"). */
113
+ launchFlags: unknown;
114
+ /** The Windows run half — injected by tests, the real one otherwise. */
115
+ windowsChrome: (options: WindowsChromeRunOptions) => Promise<WindowsChromeRun>;
116
+ /** The Windows-side executables this host carries, in preference order and
117
+ * in their Windows spelling — located through the interop mount, `[]` off
118
+ * WSL. A run folds them into its candidate list (they are never probed: a
119
+ * Windows binary answers `note`, never a version) so the picker can name the
120
+ * executable a run drives instead of hiding it. */
121
+ windowsExecutables: () => string[];
122
+ /** The live mutable state. */
123
+ state: ControllerState;
124
+ /** Bind the configuration form to this controller (the first call also serves
125
+ * as the mount's first read, so the registration run fires off the first
126
+ * commit's nonce diffs instead of being called separately). */
127
+ attachForm(form: ChromeMcpForm): void;
128
+ /** Drop the form again — the references stand in for the layers until it
129
+ * returns. */
130
+ detachForm(): void;
131
+ /** Route one configuration-form commit: re-derive the default answers, and
132
+ * run one executable refresh on the fetch trigger. */
133
+ onFormCommit(): void;
134
+ /** Run one executable refresh (probe the candidates, merge what is found
135
+ * into the saved rows, seed a never-configured host) and re-probe the
136
+ * selection — the whole fetch the card's **Fetch executables** fires. Runs
137
+ * are serialized so rapid actions never interleave. */
138
+ run(): Promise<unknown>;
139
+ /** Read the configuration form's live layers — the same read every commit
140
+ * and every run makes (the references, plus the described row once it
141
+ * exists). A headless surface (the slash commands) reads the saved rows
142
+ * through it. */
143
+ source(): ConfigLayers;
144
+ /** The live mirror — every answer the Host has standing. Headless surfaces
145
+ * (the slash commands) read their answers off it and write nothing to it:
146
+ * answers belong to the controller's own modules. */
147
+ readonly live: ConfigLiveFields;
148
+ /** Write one executable selection through the Host write-back channel — the
149
+ * same persisted `chromePath` field the card's picker writes — and re-fire
150
+ * the run behind it. `""` clears the user layer back to the row config. */
151
+ selectChromePath(path: string): Promise<void>;
152
+ /** Run the Windows Chrome path once (locate, prereq, port, launch, wait for
153
+ * the bind) on the same one-run-at-a-time chain the button drives through,
154
+ * and answer with what the run stated. */
155
+ prelaunchWindowsChrome(): Promise<string>;
156
+ /** Mirror what one live connection answered it runs with (./connections.ts).
157
+ * Every kind `resolve` ends with this. */
158
+ noteRunning(entry: {
159
+ id: string;
160
+ }, answers: RunningAnswers): void;
161
+ /** Drive the prelaunch machinery once for a live `chrome-windows`
162
+ * connection's async `resolve`. */
163
+ prelaunchForConnection(): Promise<WindowsChromeRun>;
164
+ /** Mark the standalone-config translation dismissed (./../migration.ts
165
+ * D4): the row's `migrationDismissed` flips true so the offer stops. */
166
+ dismissMigration(): void;
167
+ /** Stand this instance down: nothing late (the bounded retry behind a failed
168
+ * run most of all) may fire runs for an instance that no longer exists. A
169
+ * hot re-apply disposes the prior instance this way. */
170
+ dispose(): void;
171
+ }
172
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/host/controller/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/host/controller/state.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import type { WindowsChromeRun } from "../types/index.js";
2
+ import type { Controller } from "./state.js";
3
+ /**
4
+ * One **Prelaunch Windows Chrome** run. When the host is not WSL there is simply
5
+ * nothing to drive and the answer is `not-applicable`; otherwise the state moves
6
+ * through `launching` while the run (locate, prereq, launch, port) settles, and
7
+ * the settled state is mirrored before the run is returned.
8
+ */
9
+ export declare function runWindowsChrome(controller: Controller): Promise<WindowsChromeRun>;
10
+ /**
11
+ * The kind-side half of the run: a live `chrome-windows` connection's async
12
+ * `resolve` drives the launch through the same one-run-at-a-time chain the
13
+ * button uses, and gets the run result back to turn into the connect-mode
14
+ * stdio config.
15
+ */
16
+ export declare function prelaunchWindowsForConnection(controller: Controller): Promise<WindowsChromeRun>;
17
+ //# sourceMappingURL=windows-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-run.d.ts","sourceRoot":"","sources":["../../../src/host/controller/windows-run.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,mBAAmB,CAAC;AAI9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkExF;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAOrG"}