@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,26 @@
1
+ /**
2
+ * Controller — live-mirror announcements.
3
+ *
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).
8
+ */
9
+ import type { BridgeStderrNotice } from "../types/index.js";
10
+ import type { Controller } from "./state.js";
11
+ /**
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
15
+ * Windows binary answers `--version` just fine across the interop boundary, so a
16
+ * healthy-looking pill is exactly what a broken Windows selection looks like
17
+ * until the first tool call fails.
18
+ */
19
+ export declare function noteSelection(controller: Controller): void;
20
+ /**
21
+ * Announce where the bridge's console output goes — one line per change of
22
+ * state, keyed on what actually happened, so neither the "log" capture nor
23
+ * a switch to console echo is silent.
24
+ */
25
+ export declare function noteStderr(controller: Controller, built: BridgeStderrNotice): void;
26
+ //# sourceMappingURL=notes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../../src/host/controller/notes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAM5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAe1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAUlF"}
@@ -0,0 +1,44 @@
1
+ import { flagsSkipCheck } from "../flags.js";
2
+ import { isWindowsExecutablePath } from "../platform.js";
3
+ import { publishLive } from "./publish.js";
4
+ /**
5
+ * Publish the resolved selection into the mirror — with the one state the card
6
+ * can only learn from here, and with the static notice that goes with it. The
7
+ * Windows-executable state is keyed on the *selection*, not on any probe: a
8
+ * Windows binary answers `--version` just fine across the interop boundary, so a
9
+ * healthy-looking pill is exactly what a broken Windows selection looks like
10
+ * until the first tool call fails.
11
+ */
12
+ export function noteSelection(controller) {
13
+ const { state } = controller;
14
+ state.live.effectiveChromePath = state.runningChromePath;
15
+ state.live.effectiveSource = state.runningChromeSource;
16
+ const windowsUnderWsl = !flagsSkipCheck(state.runningFlags) && controller.wslHost && isWindowsExecutablePath(state.runningChromePath);
17
+ state.live.wslWindowsExecutable = windowsUnderWsl;
18
+ // The log's pointer is the run, named: a headless host sees no notice, and
19
+ // "connect mode" on its own is not an action.
20
+ if (windowsUnderWsl && !state.wslNoticeShown) {
21
+ state.wslNoticeShown = true;
22
+ controller.ctx.logger.warn(`dsh-chrome-mcp(${controller.config.serverName}): running under WSL with a Windows executable selected ("${state.runningChromePath}") — that binary cannot be launched from here; run Prelaunch Windows Chrome (the card's action, or the prelaunch_windows_chrome tool) to drive it in connect mode`);
23
+ }
24
+ publishLive(controller);
25
+ }
26
+ /**
27
+ * Announce where the bridge's console output goes — one line per change of
28
+ * state, keyed on what actually happened, so neither the "log" capture nor
29
+ * a switch to console echo is silent.
30
+ */
31
+ export function noteStderr(controller, built) {
32
+ const { state } = controller;
33
+ const key = built.redirect !== "" ? `file:${built.redirect}` : "console";
34
+ if (state.stderrNotice === key)
35
+ return;
36
+ state.stderrNotice = key;
37
+ if (built.redirect !== "") {
38
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): bridge stderr → ${built.redirect}`);
39
+ }
40
+ else {
41
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): bridge stderr → console (echo)`);
42
+ }
43
+ }
44
+ //# sourceMappingURL=notes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notes.js","sourceRoot":"","sources":["../../../src/host/controller/notes.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,UAAsB;IAChD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,mBAAmB,CAAC;IACvD,MAAM,eAAe,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,OAAO,IAAI,uBAAuB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACtI,KAAK,CAAC,IAAI,CAAC,oBAAoB,GAAG,eAAe,CAAC;IAClD,2EAA2E;IAC3E,8CAA8C;IAC9C,IAAI,eAAe,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QAC3C,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;QAC5B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CACtB,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,6DAA6D,KAAK,CAAC,iBAAiB,mKAAmK,CACxS,CAAC;IACN,CAAC;IACD,WAAW,CAAC,UAAU,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,UAAsB,EAAE,KAAyB;IACxE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,IAAI,KAAK,CAAC,YAAY,KAAK,GAAG;QAAE,OAAO;IACvC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC;IACzB,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QACxB,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,sBAAsB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrH,CAAC;SAAM,CAAC;QACJ,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,mCAAmC,CAAC,CAAC;IAClH,CAAC;AACL,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ChromeExecutableEntry } from "../types/index.js";
2
+ import type { Controller } from "./state.js";
3
+ /** Persist one seeded/executable selection — the row-config fallback disappears
4
+ * the moment a path is picked, so a run that seeded one writes it exactly once. */
5
+ export declare function persistChromePath(controller: Controller, path: string): Promise<void>;
6
+ /** Persist the saved-executables rows a run merged into. */
7
+ export declare function persistExecutables(controller: Controller, entries: ChromeExecutableEntry[]): Promise<void>;
8
+ /** Persist the ids of rows the user dropped, so no later merge step folds them
9
+ * back in (see ../schema.ts `droppedExecutables`). */
10
+ export declare function persistDroppedExecutables(controller: Controller, ids: readonly string[]): Promise<void>;
11
+ /** Remember that this row's standalone-config translation was turned down
12
+ * (./../migration.ts D4). This is the only Host write the proposal path makes:
13
+ * the config itself is read, never rewritten, and nothing lands in the manager's
14
+ * `servers` without a click. */
15
+ export declare function dismissMigration(controller: Controller): void;
16
+ //# sourceMappingURL=persist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../../src/host/controller/persist.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,mBAAmB,CAAC;AAG9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwC7C;mFACmF;AACnF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErF;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1G;AAED;sDACsD;AACtD,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvG;AAED;;;gCAGgC;AAChC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAE7D"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Controller — persisting what the Host itself writes.
3
+ *
4
+ * Four writes may land back in the profile patch: the seeded executable, the
5
+ * saved rows a merged scan folded in, the ids of dropped rows, and the dismissed
6
+ * translation flag (./../migration.ts D4). Since dsh 0.2.0 the store is the
7
+ * profile's **own patch layer** (there is no `settings.yaml` any more) and the
8
+ * write goes through the `settings` service keyed by the row's profile **entry
9
+ * id** — the same key the card addresses by.
10
+ *
11
+ * What gets written is only ever a user-authored field — one field per write, so
12
+ * an unrelated edit the user made in the same layer keeps standing — and it goes
13
+ * through `settings.mutate(entryId, ops)` with the write's own `set` op first and
14
+ * then one `unset` op for **every live-mirror field** (see ../values.ts
15
+ * `liveMirrorKeys`). Why the unset ops belong to the write itself: a persisted
16
+ * write re-persists the volatile fields it answers, and whatever the live publish
17
+ * stands in the running references is answered through them, so a live answer can
18
+ * ride a save back into the patch file (measured live 2026-10-12: booting the
19
+ * plugin with no user write filled the profile's own `cordis.patch.yml` row with
20
+ * every live key). An `unset` returns the field to whatever the **row config**
21
+ * answers — the row's own patch layer is excluded underneath it — so what stands
22
+ * is the row's answer and a live-only answer drops out: the live boundary holds
23
+ * from the write channel, not from a check. And it heals: the first write to a
24
+ * row that already carries leaked live keys clears them.
25
+ *
26
+ * Every write still lands on the same follow-up rule (see ./commits.ts for the
27
+ * card's copy of it): a stored-layer write resets the live-only volatile fields
28
+ * back to their row-config answers, so the mirror goes straight back out with it.
29
+ *
30
+ * All three follow the same rules: the write is answered from the run's neutral
31
+ * async context (see ./runs.ts — a write still sitting inside the write
32
+ * transaction its own form commit opened is a *nested* transaction, which the
33
+ * platform refuses instead of queueing), and it never throws out of the run. The
34
+ * mirror is what the card reads, and a failed write must not break an otherwise
35
+ * successful run.
36
+ */
37
+ import { createPersister } from "@comecaramelos/dsh-ancesters/host";
38
+ import { liveMirrorKeys } from "../values.js";
39
+ import { MIGRATION_DISMISSED_FIELD } from "../constants.js";
40
+ import { publishLive } from "./publish.js";
41
+ /** One persister per controller (ancestros' `createPersister`): the write's own
42
+ * field first, then one `unset` per live-mirror field, no revision fence (the
43
+ * Host putting its own answer into the row, not an editor saving a view — a
44
+ * stale view must not lose the seed / the merged rows / the connect flag the
45
+ * run just produced), and the mirror re-asserted after the write **and** after
46
+ * a refused one (measured live 2026-10-13: a refused rows merge on a read-only
47
+ * row otherwise left the references answering no `lastError` ever again). */
48
+ const persisters = new WeakMap();
49
+ function persisterOf(controller) {
50
+ let persister = persisters.get(controller);
51
+ if (persister === void 0) {
52
+ persister = createPersister(controller.ctx, {
53
+ form: {
54
+ current: () => {
55
+ const form = controller.state.form;
56
+ if (form === void 0)
57
+ return void 0;
58
+ const settings = form.settings ?? controller.ctx.get("settings");
59
+ return { entryId: form.entryId, settings: settings };
60
+ },
61
+ liveKeys: () => liveMirrorKeys(),
62
+ attached: () => controller.state.form !== void 0
63
+ },
64
+ liveKeys: liveMirrorKeys(),
65
+ publishLive: () => publishLive(controller),
66
+ name: `dsh-chrome-mcp(${controller.config.serverName})`
67
+ });
68
+ persisters.set(controller, persister);
69
+ }
70
+ return persister;
71
+ }
72
+ /** Write one user-authored field into the row's own patch layer, clearing every
73
+ * live-mirror field back to its row-config answer (see the module header). */
74
+ function persist(controller, field, value, note) {
75
+ return persisterOf(controller)({ [field]: value }, `dsh-chrome-mcp(${controller.config.serverName}): ${note}`);
76
+ }
77
+ /** Persist one seeded/executable selection — the row-config fallback disappears
78
+ * the moment a path is picked, so a run that seeded one writes it exactly once. */
79
+ export function persistChromePath(controller, path) {
80
+ return persist(controller, "chromePath", path, "failed to persist the seeded chromePath");
81
+ }
82
+ /** Persist the saved-executables rows a run merged into. */
83
+ export function persistExecutables(controller, entries) {
84
+ return persist(controller, "executables", entries, "failed to persist the executable rows");
85
+ }
86
+ /** Persist the ids of rows the user dropped, so no later merge step folds them
87
+ * back in (see ../schema.ts `droppedExecutables`). */
88
+ export function persistDroppedExecutables(controller, ids) {
89
+ return persist(controller, "droppedExecutables", [...ids], "failed to persist the dropped executable ids");
90
+ }
91
+ /** Remember that this row's standalone-config translation was turned down
92
+ * (./../migration.ts D4). This is the only Host write the proposal path makes:
93
+ * the config itself is read, never rewritten, and nothing lands in the manager's
94
+ * `servers` without a click. */
95
+ export function dismissMigration(controller) {
96
+ void persist(controller, MIGRATION_DISMISSED_FIELD, true, "failed to persist the dismissed translation");
97
+ }
98
+ //# sourceMappingURL=persist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../../src/host/controller/persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,eAAe,EAAoB,MAAM,mCAAmC,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAG5D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;;;6EAM6E;AAC7E,MAAM,UAAU,GAAG,IAAI,OAAO,EAA2B,CAAC;AAE1D,SAAS,WAAW,CAAC,UAAsB;IACvC,IAAI,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,SAAS,KAAK,KAAK,CAAC,EAAE,CAAC;QACvB,SAAS,GAAG,eAAe,CAAC,UAAU,CAAC,GAAY,EAAE;YACjD,IAAI,EAAE;gBACF,OAAO,EAAE,GAAG,EAAE;oBACV,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;oBACnC,IAAI,IAAI,KAAK,KAAK,CAAC;wBAAE,OAAO,KAAK,CAAC,CAAC;oBACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAK,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAA+B,CAAC;oBAChG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAiB,EAAE,CAAC;gBAClE,CAAC;gBACD,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE;gBAChC,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;aACnD;YACD,QAAQ,EAAE,cAAc,EAAE;YAC1B,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC;YAC1C,IAAI,EAAE,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG;SAC1D,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;8EAC8E;AAC9E,SAAS,OAAO,CAAC,UAAsB,EAAE,KAAa,EAAE,KAAc,EAAE,IAAY;IAChF,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,MAAM,IAAI,EAAE,CAAC,CAAC;AACnH,CAAC;AAED;mFACmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,UAAsB,EAAE,IAAY;IAClE,OAAO,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,yCAAyC,CAAC,CAAC;AAC9F,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,UAAsB,EAAE,OAAgC;IACvF,OAAO,OAAO,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,uCAAuC,CAAC,CAAC;AAChG,CAAC;AAED;sDACsD;AACtD,MAAM,UAAU,yBAAyB,CAAC,UAAsB,EAAE,GAAsB;IACpF,OAAO,OAAO,CAAC,UAAU,EAAE,oBAAoB,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,8CAA8C,CAAC,CAAC;AAC/G,CAAC;AAED;;;gCAGgC;AAChC,MAAM,UAAU,gBAAgB,CAAC,UAAsB;IACnD,KAAK,OAAO,CAAC,UAAU,EAAE,yBAAyB,EAAE,IAAI,EAAE,6CAA6C,CAAC,CAAC;AAC7G,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Controller } from "./state.js";
2
+ /** Queue one coalesced publish. */
3
+ export declare function publishLive(controller: Controller): void;
4
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/host/controller/publish.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAiCxD"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Controller — publishing the live mirror.
3
+ *
4
+ * Every answer the card reads (`lastError`, the per-path probe list, the resolved
5
+ * selection, the Windows run state, …) is a `.volatile()` field of the same
6
+ * `Config` the card edits, so publishing is one **volatile commit** — and that
7
+ * channel is `createLiveMirror` from `@comecaramelos/dsh-ancesters/host`: the
8
+ * coalescing, the wait for the fiber to settle, the loader-entry merge that
9
+ * persists nothing and never remounts, the `describe()` that turns the new
10
+ * revision into the event the card settles on, and the re-assert when a settings
11
+ * write anywhere in the profile resets the live keys (dsh 0.2.1).
12
+ *
13
+ * What stays here is what the mirror *means* for this row: the connect-mode
14
+ * answer, derived on every publish, and telling the manager that what a picker
15
+ * would answer just moved.
16
+ */
17
+ import { createLiveMirror } from "@comecaramelos/dsh-ancesters/host";
18
+ import { flagsSkipCheck } from "../flags.js";
19
+ /** Queue one coalesced publish. */
20
+ export function publishLive(controller) {
21
+ const { state } = controller;
22
+ // The connect-mode answer is re-derived here, off what answers connect
23
+ // mode right now: a connection whose running flags carry the debug URL, or
24
+ // a live **Prelaunch Windows Chrome** run that stands connected against its
25
+ // port. Connect mode is a property of the running argv, not of a flags
26
+ // *change* — answering only where a flags list was applied left a row that
27
+ // already runs in connect mode serving the pill as the local selection
28
+ // (measured live 2026-10-13: a host booted with
29
+ // `--browserUrl=http://127.0.0.1:9223` in its row config never read Connect
30
+ // mode; the pill read the executable name and only turned over when the
31
+ // run applied the flags itself). Deriving on every publish means the answer
32
+ // can never be quieter than what is running.
33
+ state.live.carriesConnectionMode = flagsSkipCheck(state.runningFlags) || (state.live.windowsChromeStatus.state === "connected" && state.live.windowsChromeStatus.port > 0);
34
+ if (state.mirror === void 0) {
35
+ state.mirror = createLiveMirror(controller.ctx, {
36
+ name: `dsh-chrome-mcp(${controller.config.serverName})`,
37
+ read: () => ({ ...state.live }),
38
+ settings: () => (controller.state.form?.settings ?? controller.ctx.get("settings"))
39
+ });
40
+ }
41
+ state.mirror.publish();
42
+ // The connection fields' `select` choices are Host-served answers read off
43
+ // this very state (the catalog, the scan answers, what a live connection
44
+ // runs with), so every publish says "what a picker would answer just
45
+ // moved" — once per turn, like the publish itself (see ../manager.ts:
46
+ // "every publish re-notifies").
47
+ if (state.kindsNotifyQueued)
48
+ return;
49
+ state.kindsNotifyQueued = true;
50
+ queueMicrotask(() => {
51
+ state.kindsNotifyQueued = false;
52
+ if (!state.disposed)
53
+ state.notifyKindsChanged();
54
+ });
55
+ }
56
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/host/controller/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAK7C,mCAAmC;AACnC,MAAM,UAAU,WAAW,CAAC,UAAsB;IAC9C,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,uEAAuE;IACvE,2EAA2E;IAC3E,4EAA4E;IAC5E,uEAAuE;IACvE,2EAA2E;IAC3E,uEAAuE;IACvE,gDAAgD;IAChD,4EAA4E;IAC5E,wEAAwE;IACxE,4EAA4E;IAC5E,6CAA6C;IAC7C,KAAK,CAAC,IAAI,CAAC,qBAAqB,GAAG,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC3K,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAY,EAAE;YACrD,IAAI,EAAE,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG;YACvD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAA4B;YAC1D,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,IAAK,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAA+B,CAAU;SAC9H,CAAC,CAAC;IACP,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IACvB,2EAA2E;IAC3E,yEAAyE;IACzE,qEAAqE;IACrE,sEAAsE;IACtE,gCAAgC;IAChC,IAAI,KAAK,CAAC,iBAAiB;QAAE,OAAO;IACpC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAC/B,cAAc,CAAC,GAAG,EAAE;QAChB,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,80 @@
1
+ import type { ChromeExecutableEntry, ChromeExecutableStatus, EffectiveChromeSource } from "../types/index.js";
2
+ import type { Controller } from "./state.js";
3
+ /** The serialized units one controller may queue. */
4
+ export type RunKind = "refresh" | "probe" | "windows";
5
+ /** Element-wise equality of two saved-row lists (order is the dropdown order). */
6
+ export declare function sameEntries(a: readonly ChromeExecutableEntry[], b: readonly ChromeExecutableEntry[]): boolean;
7
+ /**
8
+ * Fold the legacy hand-typed MRU into the rows, exactly once. It is the same list
9
+ * the older card used to write, so reading it never duplicates a row the card
10
+ * already saved: the merge keeps stored rows and only appends ids that are
11
+ * missing, and the result lands in the persisted rows instead of staying
12
+ * readable forever as a second source.
13
+ */
14
+ export declare function mergeLegacyPaths(controller: Controller, skip?: ReadonlySet<string>): ChromeExecutableEntry[];
15
+ /**
16
+ * One executable run. Probe every candidate the row config and the saved rows
17
+ * carry (plus the selection — the same path may appear as a row), publish what
18
+ * answered as per-path status, and merge what was found into the saved rows,
19
+ * keeping the names their user gave them. When nothing is configured at all
20
+ * (neither layer carries a path) the first runnable entry is **seeded**: written
21
+ * into the persisted `chromePath` once, so what the picker shows is what the
22
+ * bridge runs. A selection that is already fixed is never re-resolved, however
23
+ * broken.
24
+ * @returns the per-path statuses the run answered with.
25
+ */
26
+ export declare function runExecutableDiscovery(controller: Controller): Promise<ChromeExecutableStatus[]>;
27
+ /**
28
+ * The probe of the *selection* — the one run that answers the version line the
29
+ * card shows under the pill. Nothing probed (no selection, or a connect-mode
30
+ * flag) must not clear anything: upstream starts the browser lazily, so silence
31
+ * is not health.
32
+ */
33
+ export declare function probeSelection(controller: Controller): Promise<string>;
34
+ /**
35
+ * Write one executable selection through the Host write-back channel — the same
36
+ * persisted `chromePath` field every other surface reads — and re-fire the run
37
+ * behind it, the way the card's own selection commit does: a changed selection
38
+ * shifts the default answers (connections follow, the run re-runs), an
39
+ * unchanged write just re-probes. This is the command-side mirror of the
40
+ * picker — pill, command and catalog read and write one field — so a headless
41
+ * selection lands exactly where a GUI pick would.
42
+ */
43
+ export declare function selectChromePath(controller: Controller, path: string): Promise<void>;
44
+ /**
45
+ * Carry a different executable into the live answers — the argv tail carries
46
+ * `--executablePath=<path>`, so unlike a flags edit this one is what the card's
47
+ * pill claims is running. What lives stands on is not restarted here: a
48
+ * connection that follows the row's default is handed back to the pool for a
49
+ * re-resolve, and one that picked its own executable was never following it.
50
+ * `rerun` schedules the scan+probe that follows a selection change; a caller
51
+ * that is already inside that run (the seeding branch above) passes `false`.
52
+ */
53
+ export declare function applyChromePath(controller: Controller, path: string, nextSource: EffectiveChromeSource, rerun?: boolean): void;
54
+ /** Cancel the pending bounded retry — what the instance's dispose calls. */
55
+ export declare function cancelDiscoveryRetry(controller: Controller): void;
56
+ /**
57
+ * Serialize one unit of work: a rows-only refresh, a run that also re-probes
58
+ * what is selected, or the Windows Chrome launch. Windows runs share this chain
59
+ * because the invariant is "one run at a time" — nothing about it interacts with
60
+ * the local probe. The body answers from a neutral async context (see
61
+ * `runContext`): a run scheduled from a form commit must not carry that
62
+ * commit's write transaction, or every write the run answers would be refused
63
+ * as a nested transaction.
64
+ */
65
+ export declare function queue(controller: Controller, kind: RunKind): Promise<unknown>;
66
+ /**
67
+ * One Windows Chrome run on demand: queued on the same chain as the button (one
68
+ * run at a time), resolved once it settled. The answer is the live mirror read
69
+ * after the run — the tool surface says what `windowsChromeStatus` says, never
70
+ * more than the run answered.
71
+ *
72
+ * With the manager mounted this is also the surface that keeps the live
73
+ * `chrome-windows` connections honest: a run that connected while such a
74
+ * connection stands is a reason to answer that connection again (the run is
75
+ * idempotent — the live port rides into `currentFlags` — so re-answering is not
76
+ * a second browser), and a run that connected without one is said to be worth
77
+ * one.
78
+ */
79
+ export declare function prelaunchWindowsChrome(controller: Controller): Promise<string>;
80
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../../src/host/controller/runs.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAQ9G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,qDAAqD;AACrD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAoBtD,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,qBAAqB,EAAE,EAAE,CAAC,EAAE,SAAS,qBAAqB,EAAE,GAAG,OAAO,CAG7G;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,qBAAqB,EAAE,CAe5G;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CA6FtG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAsC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,qBAAqB,EAAE,KAAK,UAAO,GAAG,IAAI,CAW3H;AAqDD,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAMjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBpF"}