@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
@@ -10,8 +10,11 @@
10
10
  import { bridgeConfig } from "../bridge.js";
11
11
  import { flagsSkipCheck } from "../flags.js";
12
12
  import { noteStderr } from "./notes.js";
13
- /** The row config as the bridge/config builders see it: effective executable,
14
- * cleaned row flags. The logical argv shape is unchanged. */
13
+ import { publishLive } from "./publish.js";
14
+ /** The bridge's own view of one config: the ordinary passthroughs ride along
15
+ * verbatim, and the two levers the run owns — the flags list and the resolved
16
+ * selection — are handed in explicitly, so nothing here mistakes a reference for
17
+ * a value. The logical argv shape is unchanged. */
15
18
  export function configForBridge(controller, flags) {
16
19
  return { ...controller.config, extraFlags: flags, chromePath: controller.state.runningChromePath };
17
20
  }
@@ -31,10 +34,17 @@ export function restartBridge(controller, built, note) {
31
34
  void Promise.resolve(controller.bridge)
32
35
  .then(() => controller.bridge.update(built.config))
33
36
  .then(() => {
34
- controller.state.entry.lastError = "";
37
+ // A successful bridge update proves the flags landed and the
38
+ // bridge connected again — it clears the captured *connection*
39
+ // error — but it says nothing about the executable: the known
40
+ // executable-missing answer stands until a probe answers a
41
+ // version or a tool call succeeds.
42
+ if (!controller.state.live.chromeMissing)
43
+ controller.state.live.lastError = "";
44
+ publishLive(controller);
35
45
  // Intentionally NOT clearing `chromeMissing`: a successful bridge
36
- // update proves the flags took (clears the captured connection error)
37
- // but says nothing about the executable.
46
+ // update proves the flags took but says nothing about the
47
+ // executable.
38
48
  })
39
49
  .catch((error) => controller.ctx.logger.error(`chrome-devtools-mcp(${controller.config.serverName}): ${note}: ${String(error)}`));
40
50
  }
@@ -42,11 +52,15 @@ export function restartBridge(controller, built, note) {
42
52
  export function applyFlags(controller, flags) {
43
53
  const { state } = controller;
44
54
  state.runningFlags = flags;
45
- state.entry.carriesConnectionMode = flagsSkipCheck(flags);
55
+ // No mirror answer here: `publishLive` below re-derives it from the list the
56
+ // bridge launches with (`src/host/controller/publish.ts`), so setting it off
57
+ // this call's argument would be the same answer twice. The known-error gate
58
+ // reads the predicate directly for the same reason.
46
59
  // Connect mode launches no local executable, so the known "executable
47
60
  // missing" state simply does not apply while it is set.
48
- if (state.entry.carriesConnectionMode)
49
- state.entry.chromeMissing = false;
61
+ if (flagsSkipCheck(flags))
62
+ state.live.chromeMissing = false;
63
+ publishLive(controller);
50
64
  controller.ctx.logger.info(`chrome-devtools-mcp(${controller.config.serverName}): relaunching bridge with flags [${flags.join(" ")}]`);
51
65
  const built = bridgeConfig(configForBridge(controller, flags), flags, state.runningStderrMode);
52
66
  noteStderr(controller, built);
@@ -61,6 +75,8 @@ export function applyFlags(controller, flags) {
61
75
  export function applyStderrMode(controller, mode) {
62
76
  const { state } = controller;
63
77
  state.runningStderrMode = mode;
78
+ state.live.stderrEffective = mode;
79
+ publishLive(controller);
64
80
  controller.ctx.logger.info(`chrome-devtools-mcp(${controller.config.serverName}): bridge stderr mode → "${mode}" (restarting the bridge connection)`);
65
81
  const built = bridgeConfig(configForBridge(controller, state.runningFlags), state.runningFlags, mode);
66
82
  noteStderr(controller, built);
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-run.js","sourceRoot":"","sources":["../../../src/host/controller/bridge-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC;6DAC6D;AAC7D,MAAM,UAAU,eAAe,CAAC,UAAsB,EAAE,KAAe;IACnE,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;AACvG,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,UAAsB,EAAE,KAAsC,EAAE,IAAY;IACtG,KAAK,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;SAClC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAClD,IAAI,CAAC,GAAG,EAAE;QACP,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;QACtC,kEAAkE;QAClE,sEAAsE;QACtE,yCAAyC;IAC7C,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,UAAU,CAAC,MAAM,CAAC,UAAU,MAAM,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1I,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,UAAsB,EAAE,KAAe;IAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;IAC3B,KAAK,CAAC,KAAK,CAAC,qBAAqB,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1D,sEAAsE;IACtE,wDAAwD;IACxD,IAAI,KAAK,CAAC,KAAK,CAAC,qBAAqB;QAAE,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;IACzE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,MAAM,CAAC,UAAU,qCAAqC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvI,MAAM,KAAK,GAAG,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/F,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9B,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,UAAsB,EAAE,IAAsB;IAC1E,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,MAAM,CAAC,UAAU,4BAA4B,IAAI,sCAAsC,CAAC,CAAC;IACtJ,MAAM,KAAK,GAAG,YAAY,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACtG,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9B,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,iCAAiC,IAAI,UAAU,CAAC,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"bridge-run.js","sourceRoot":"","sources":["../../../src/host/controller/bridge-run.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,15 @@
1
1
  import type { Controller } from "./state.js";
2
- /**
3
- * Fold bridge log lines into the base layer. dsh-mcp-client reports connection
4
- * problems only through its logger (reconnect warnings with "connection
5
- * failed/lost", give-up errors, spawn failures), and a module plugin has no
6
- * push channel to clients — so the newest failure line becomes `lastError`, and
7
- * the "reconnected and re-synced tools" success line clears it. The wrapper
8
- * lives only on the bridge scope; our own logs bypass it, so our own warns never
9
- * masquerade as connection errors.
10
- */
11
- export declare function noteBridgeLog(controller: Controller, level: string, args: unknown[]): void;
12
2
  /**
13
3
  * Register the tool-call status capture: browser-level failures surface only as
14
- * the calling agent's tool result, never on the bridge logger, so a settled
15
- * result whose registered name is prefixed `mcp__<serverName>__` and carries
16
- * `isError` writes the failure into the base layer; a successful chrome-tool call
17
- * clears both, so the card reports current health. The body is wrapped in
18
- * try/catch (warn only — a capture fault must never break a tool call) and
19
- * returns `next()` unchanged.
4
+ * the calling agent's tool result, never on a line, so a settled result whose
5
+ * registered name is prefixed `mcp__<id>__` for one of this component's live
6
+ * connections and carries `isError` writes the failure into the live mirror; a
7
+ * successful chrome-tool call clears both, so the card reports current health.
8
+ * A success is *evidence* — what a missing selection never produces — while an
9
+ * unrelated failure line never displaces the known executable-missing answer
10
+ * standing (the rule the old bridge-log capture followed too). The body is
11
+ * wrapped in try/catch (warn only — a capture fault must never break a tool
12
+ * call) and returns `next()` unchanged.
20
13
  */
21
14
  export declare function registerToolCapture(controller: Controller): void;
22
15
  //# sourceMappingURL=captures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"captures.d.ts","sourceRoot":"","sources":["../../../src/host/controller/captures.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAW1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAgBhE"}
1
+ {"version":3,"file":"captures.d.ts","sourceRoot":"","sources":["../../../src/host/controller/captures.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAkBhE"}
@@ -1,60 +1,85 @@
1
1
  /**
2
- * Controller — the two capture paths that reach the base layer.
2
+ * Controller — the tool-call result capture that reaches the live mirror.
3
3
  *
4
- * A module plugin has no push channel to clients, so both capture paths write
5
- * straight into the base layer: the newest bridge-log failure line becomes
6
- * `lastError`, and a settled browser-tool result that failed does the same (the
7
- * two never duplicate — bridge logs never reach the tool surface and vice
8
- * versa). Each capture is classified into the known "executable missing" flag so
9
- * the single red status dot keeps its whole story.
10
- */
11
- import { BRIDGE_RECONNECTED } from "../constants.js";
12
- import { firstLine, isChromeMissing, toolResultNote } from "../status.js";
13
- /**
14
- * Fold bridge log lines into the base layer. dsh-mcp-client reports connection
15
- * problems only through its logger (reconnect warnings with "connection
16
- * failed/lost", give-up errors, spawn failures), and a module plugin has no
17
- * push channel to clients — so the newest failure line becomes `lastError`, and
18
- * the "reconnected and re-synced tools" success line clears it. The wrapper
19
- * lives only on the bridge scope; our own logs bypass it, so our own warns never
20
- * masquerade as connection errors.
4
+ * A settled browser-tool result that failed becomes the newest `lastError`,
5
+ * classified into the known "executable missing" flag so the single red status
6
+ * dot keeps its whole story. The write is a live mirror write: published through
7
+ * the references, never persisted.
8
+ *
9
+ * What the bridge-log capture used to be, the connection lines are now: every
10
+ * failure the nested fiber answers with reaches the manager's own line for the
11
+ * entry that spawned it, and the tool-call surface is the one failure path that
12
+ * never reaches any line — a browser-level problem (target closed, dialog stuck,
13
+ * protocol timeout) is returned to the calling agent and lands nowhere else.
14
+ * Hence only the tool capture survives here.
15
+ *
16
+ * The prefix rule changed with the component model: a connection publishes under
17
+ * `mcp__<entry id>__`, where the entry id is the manager's, not the row's old
18
+ * `serverName`. So the capture answers for whichever live connection of this
19
+ * component's own kinds carries the tool; a tool outside this component's
20
+ * namespace never touches the mirror.
21
21
  */
22
- export function noteBridgeLog(controller, level, args) {
23
- const message = args
24
- .map((arg) => (arg instanceof Error ? (arg.stack ?? arg.message ?? String(arg)) : String(arg)))
25
- .join(" ");
26
- if (level === "error" || level === "warn") {
27
- controller.state.entry.lastError = firstLine(message);
28
- controller.state.entry.chromeMissing = isChromeMissing(message);
29
- }
30
- else if (level === "info" && BRIDGE_RECONNECTED.test(message)) {
31
- controller.state.entry.lastError = "";
32
- controller.state.entry.chromeMissing = false;
33
- }
34
- }
22
+ import { captureToolResults } from "@comecaramelos/dsh-ancesters/host";
23
+ import { isChromeMissing } from "../status.js";
24
+ import { publishLive } from "./publish.js";
35
25
  /**
36
26
  * Register the tool-call status capture: browser-level failures surface only as
37
- * the calling agent's tool result, never on the bridge logger, so a settled
38
- * result whose registered name is prefixed `mcp__<serverName>__` and carries
39
- * `isError` writes the failure into the base layer; a successful chrome-tool call
40
- * clears both, so the card reports current health. The body is wrapped in
41
- * try/catch (warn only — a capture fault must never break a tool call) and
42
- * returns `next()` unchanged.
27
+ * the calling agent's tool result, never on a line, so a settled result whose
28
+ * registered name is prefixed `mcp__<id>__` for one of this component's live
29
+ * connections and carries `isError` writes the failure into the live mirror; a
30
+ * successful chrome-tool call clears both, so the card reports current health.
31
+ * A success is *evidence* — what a missing selection never produces — while an
32
+ * unrelated failure line never displaces the known executable-missing answer
33
+ * standing (the rule the old bridge-log capture followed too). The body is
34
+ * wrapped in try/catch (warn only — a capture fault must never break a tool
35
+ * call) and returns `next()` unchanged.
43
36
  */
44
37
  export function registerToolCapture(controller) {
45
- const toolPrefix = `mcp__${controller.config.serverName}__`;
46
- controller.ctx.on("tools/post-execute", async (exec, result, next) => {
47
- try {
48
- if (typeof exec.name === "string" && exec.name.startsWith(toolPrefix)) {
49
- const note = toolResultNote(exec.name, result);
50
- controller.state.entry.lastError = note ?? "";
51
- controller.state.entry.chromeMissing = note === null ? false : isChromeMissing(note);
38
+ // The listener, the prefix match, the note and the never-break-a-tool-call
39
+ // wrapping are ancestros' `captureToolResults`; the prefixes are asked on
40
+ // every call, because the live connections come and go.
41
+ captureToolResults(controller.ctx, {
42
+ name: `dsh-chrome-mcp(${controller.config.serverName})`,
43
+ prefix: (name) => ownedToolPrefix(controller).some((prefix) => name.startsWith(prefix)),
44
+ onResult: (note) => {
45
+ if (note === null) {
46
+ controller.state.live.lastError = "";
47
+ controller.state.live.chromeMissing = false;
52
48
  }
49
+ else if (isChromeMissing(note) || !controller.state.live.chromeMissing) {
50
+ controller.state.live.lastError = note;
51
+ controller.state.live.chromeMissing = isChromeMissing(note);
52
+ }
53
+ publishLive(controller);
53
54
  }
54
- catch (error) {
55
- controller.ctx.logger.warn(`chrome-devtools-mcp(${controller.config.serverName}): tool status capture failed: ${String(error)}`);
56
- }
57
- return next();
58
55
  });
59
56
  }
57
+ /** The namespaces whose tool calls belong to this component: every live
58
+ * connection of the component's own kinds answers under its entry id. A tool
59
+ * named anywhere else (another component's connection, a core stdio entry) is
60
+ * simply not this component's business. */
61
+ function ownedToolPrefixes(controller) {
62
+ const service = controller.state.connections;
63
+ if (service === void 0)
64
+ return [];
65
+ const prefixes = [];
66
+ try {
67
+ for (const entry of service.entries()) {
68
+ if (entry.kind !== "chrome" && entry.kind !== "chrome-windows")
69
+ continue;
70
+ prefixes.push(`mcp__${entry.id}__`);
71
+ }
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ return prefixes;
77
+ }
78
+ function ownedToolPrefix(controller) {
79
+ const prefixes = ownedToolPrefixes(controller);
80
+ // The row's own `serverName` still names the tools while the connection was
81
+ // answered under it (the migration-era config), so a captured tool under
82
+ // that namespace is also ours.
83
+ return prefixes.length > 0 ? prefixes : [`mcp__${controller.config.serverName}__`];
84
+ }
60
85
  //# sourceMappingURL=captures.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"captures.js","sourceRoot":"","sources":["../../../src/host/controller/captures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAK1E;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,UAAsB,EAAE,KAAa,EAAE,IAAe;IAChF,MAAM,OAAO,GAAG,IAAI;SACf,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;SAC9F,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACxC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACtD,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;QACtC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;IACjD,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAsB;IACtD,MAAM,UAAU,GAAG,QAAQ,UAAU,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC;IAC3D,UAAU,CAAC,GAAG,CAAC,EAA0H,CACtI,oBAAoB,EACpB,KAAK,EAAE,IAAuB,EAAE,MAAsB,EAAE,IAAmB,EAAE,EAAE;QAC3E,IAAI,CAAC;YACD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/C,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC9C,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YACzF,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,MAAM,CAAC,UAAU,kCAAkC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrI,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"captures.js","sourceRoot":"","sources":["../../../src/host/controller/captures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAsB;IACtD,2EAA2E;IAC3E,0EAA0E;IAC1E,wDAAwD;IACxD,kBAAkB,CAAC,UAAU,CAAC,GAAY,EAAE;QACxC,IAAI,EAAE,kBAAkB,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG;QACvD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/F,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;gBACrC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAChD,CAAC;iBAAM,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACvC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC;YACD,WAAW,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;KACJ,CAAC,CAAC;AACP,CAAC;AAED;;;2CAG2C;AAC3C,SAAS,iBAAiB,CAAC,UAAsB;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;IAC7C,IAAI,OAAO,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;gBAAE,SAAS;YACzE,QAAQ,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,UAAsB;IAC3C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC/C,4EAA4E;IAC5E,yEAAyE;IACzE,+BAA+B;IAC/B,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,UAAU,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;AACvF,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import type { Controller } from "./state.js";
2
- /** Route one settings commit. */
3
- export declare function onSettingsChange(controller: Controller): void;
2
+ /** Route one configuration-form commit. */
3
+ export declare function onFormCommit(controller: Controller): void;
4
4
  //# sourceMappingURL=commits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../../src/host/controller/commits.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,iCAAiC;AACjC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAoD7D"}
1
+ {"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../../src/host/controller/commits.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CA8FzD"}
@@ -1,55 +1,106 @@
1
1
  /**
2
- * Controller — settings-commit routing.
2
+ * Controller — configuration-form commit routing.
3
3
  *
4
- * One settings commit may carry any of five changes; this routes them in the
5
- * reference's order: a flags drift restarts the bridge, an executable change
6
- * picked by the card restarts it and re-runs the discovery, a rows change is
7
- * folded into the same run (never a second one), the stderr toggle restarts the
8
- * connection with/without the stderr wrapper, and the two trigger nonces (the
9
- * fetch button, the Windows button) fire their runs. The first commit is the
10
- * registration run — a persisted Windows trigger folds in silently so booting a
11
- * host never launches a Windows browser by itself.
4
+ * One commit may carry any of five changes; this routes them in the reference's
5
+ * order: a flags drift shifts what a connection with no own answer would run
6
+ * with (and hands such live connections back to the pool), an executable change
7
+ * picked by the card does the same plus a re-run of the discovery, a rows change
8
+ * is folded into the same run (never a second one), the stderr toggle shifts the
9
+ * spawn wrapper the next answer builds with, and the two trigger nonces (the
10
+ * fetch button, the Windows button) fire their runs. The first commit read is
11
+ * the registration run — a persisted Windows trigger folds in silently so
12
+ * booting a host never launches a Windows browser by itself.
13
+ *
14
+ * Two things make this routing safe under the config-form model:
15
+ *
16
+ * - It runs only for **user-authored** paths (see ../settings.ts
17
+ * `routesUserCommit`), so the live publish it itself triggers — a volatile
18
+ * commit carrying live fields — never re-enters it.
19
+ * - It re-publishes the live mirror when it finishes. A user write clears the
20
+ * live-only fields out of the running references (the write merge), so without
21
+ * the re-publish the card would read defaults back until the next run.
22
+ *
23
+ * Nothing here restarts anything: what runs lives in the manager's pool, and
24
+ * that pool decides a restart against the config the kind's `resolve` answers
25
+ * with — this side only says what the default answers would be.
12
26
  */
13
27
  import { normalizeEntries } from "../catalog.js";
14
- import { sameFlags } from "../flags.js";
15
- import { resolveEffectiveChromePath, resolveStderrMode } from "../values.js";
16
- import { applyFlags, applyStderrMode } from "./bridge-run.js";
28
+ import { KIND_FIELDS } from "../constants.js";
29
+ import { flagsSkipCheck, sameFlags } from "../flags.js";
30
+ import { readPersistedChromePath, resolveLaunchFlags, resolveSelection, resolveStderrModeFromLayers } from "../values.js";
31
+ import { invalidateOwnedForField } from "./connections.js";
17
32
  import { applyChromePath, queue, sameEntries } from "./runs.js";
18
- /** Route one settings commit. */
19
- export function onSettingsChange(controller) {
33
+ import { publishLive } from "./publish.js";
34
+ /** Route one configuration-form commit. */
35
+ export function onFormCommit(controller) {
20
36
  const { state } = controller;
21
37
  try {
22
- const current = state.source();
23
- if (!sameFlags(current.extraFlags, state.runningFlags))
24
- applyFlags(controller, current.extraFlags);
25
- // Executable changes come from the persisted `chromePath` the card wrote
26
- // (a row's `id`). They restart the bridge connection and re-run the
27
- // discovery, because a different executable reads a different machine. A
38
+ const layers = state.source();
39
+ // Flags: the user layer, then the launch environment, then the row config,
40
+ // then the schema default. Whatever answers is what a connection following
41
+ // the row would run with; the ones carrying their own list are untouched.
42
+ const nextFlags = resolveLaunchFlags(layers, controller.launchFlags);
43
+ if (!sameFlags(nextFlags, state.runningFlags)) {
44
+ state.runningFlags = nextFlags;
45
+ // Connect mode launches no local executable, so the known "executable
46
+ // missing" state simply does not apply while it is set.
47
+ if (flagsSkipCheck(nextFlags))
48
+ state.live.chromeMissing = false;
49
+ publishLive(controller);
50
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): default flags → [${nextFlags.join(" ")}] (connections without own flags re-answer on the next prepare)`);
51
+ invalidateOwnedForField(controller, KIND_FIELDS.extraFlags);
52
+ }
53
+ // Executable changes come from the user layer `chromePath` the card wrote
54
+ // (a row's `id`) or the host seeded. A different executable reads a
55
+ // different machine: mirror the new default and re-run the discovery. A
28
56
  // path the host seeded itself keeps standing until the user picks one:
29
- // the seed is written into the persisted layer, and until that write is
57
+ // the seed is written into the user layer, and until that write is
30
58
  // visible a commit must not resolve back to "nothing selected".
31
- const userLayer = typeof current.chromePath === "string" ? current.chromePath.trim() : "";
59
+ const userLayer = readPersistedChromePath(layers);
32
60
  if (userLayer !== "")
33
61
  state.seenUserSelection = true;
34
62
  const seededCarry = state.seededPath !== "" && !state.seenUserSelection ? state.seededPath : "";
35
- const nextChromePath = resolveEffectiveChromePath(userLayer !== "" ? userLayer : seededCarry, controller.rowChromePath);
36
- const nextSource = userLayer !== "" ? "selected" : seededCarry !== "" ? "selected" : controller.rowChromePath !== "" ? "row-config" : "";
37
- if (nextChromePath !== state.runningChromePath)
63
+ const selection = resolveSelection(layers);
64
+ const nextChromePath = selection.path !== "" ? selection.path : seededCarry;
65
+ const nextSource = nextChromePath === "" ? "" : selection.source !== "" ? selection.source : "selected";
66
+ // A row config that pinned the executable with a flag answers as the
67
+ // row-config source; say it once, since the fold is invisible to argv and
68
+ // a silent switch would read as the picker having changed.
69
+ if (selection.source === "row-config" && selection.pinned === true && !state.legacyPinAnnounced) {
70
+ state.legacyPinAnnounced = true;
71
+ controller.ctx.logger.warn(`dsh-chrome-mcp(${controller.config.serverName}): an extraFlags "--executablePath" in the row config is now the \`chromePath\` source ("${selection.path}"); the flag itself is dropped from the launched argv`);
72
+ }
73
+ if (nextChromePath !== state.runningChromePath || nextSource !== state.runningChromeSource)
38
74
  applyChromePath(controller, nextChromePath, nextSource);
39
- // Rows changes touch the list, never the connection.
40
- const nextExecutables = normalizeEntries(current.executables);
75
+ // Rows changes touch the list, never a connection.
76
+ const nextExecutables = normalizeEntries(layers.user.executables ?? layers.value.executables);
41
77
  const rowsChanged = !sameEntries(nextExecutables, state.runningExecutables);
42
- // The "Reduce log output" toggle lives here too: a change of the
43
- // effective stderr mode restarts the bridge connection with / without
44
- // the stderr-capturing wrapper.
45
- const nextStderrMode = resolveStderrMode(current.stderrMode, controller.config.bridgeStderr);
46
- if (nextStderrMode !== state.runningStderrMode)
47
- applyStderrMode(controller, nextStderrMode);
78
+ // The "Reduce log output" toggle lives here too: the effective stderr mode
79
+ // is stated from every commit, not only from a switch — a commit that
80
+ // changes nothing the spawn does must still answer what the spawn *does*
81
+ // do, or the card's own diff against the effective mode would drop every
82
+ // flip it stages. A switch shifts the default and hands the connections
83
+ // that follow it back to the pool (the wrapper is fixed at spawn).
84
+ const nextStderrMode = resolveStderrModeFromLayers(layers, controller.config.bridgeStderr);
85
+ state.live.stderrEffective = nextStderrMode;
86
+ if (nextStderrMode !== state.runningStderrMode) {
87
+ state.runningStderrMode = nextStderrMode;
88
+ publishLive(controller);
89
+ controller.ctx.logger.info(`dsh-chrome-mcp(${controller.config.serverName}): bridge stderr mode → "${nextStderrMode}" (connections re-spawn with the new wrapper)`);
90
+ invalidateOwnedForField(controller, KIND_FIELDS.stderrMode);
91
+ }
92
+ // A persisted trigger must never fire a run just because the Host read
93
+ // it back: the reference pins this with `!== 0` (a stored nonce folds in
94
+ // silently, only a later diff fires). The guard here is the same rule,
95
+ // stated the stronger way: the first commit *is* the fold (booting never
96
+ // launches — see the branch below), and every later diff is real because
97
+ // the card writes `Date.now()` as the trigger value (the client's
98
+ // fetch/openWindowsChrome), so no stored value ever equals a new write.
48
99
  const firstCommit = state.lastRefreshNonce === void 0;
49
- const refreshChanged = !firstCommit && current.refreshExecutablesNonce !== state.lastRefreshNonce;
50
- const windowsChanged = !firstCommit && current.openWindowsChromeNonce !== state.lastWindowsNonce;
51
- state.lastRefreshNonce = current.refreshExecutablesNonce;
52
- state.lastWindowsNonce = current.openWindowsChromeNonce;
100
+ const refreshChanged = !firstCommit && layers.value.refreshExecutablesNonce !== state.lastRefreshNonce;
101
+ const windowsChanged = !firstCommit && layers.value.openWindowsChromeNonce !== state.lastWindowsNonce;
102
+ state.lastRefreshNonce = layers.value.refreshExecutablesNonce;
103
+ state.lastWindowsNonce = layers.value.openWindowsChromeNonce;
53
104
  if (firstCommit) {
54
105
  // The registration run: discovery + probe, no separate call. A
55
106
  // persisted Windows trigger folds in silently — booting a host must
@@ -57,9 +108,9 @@ export function onSettingsChange(controller) {
57
108
  queue(controller, "probe");
58
109
  }
59
110
  else {
60
- // The card's **Search executables** button. A rows change is folded
61
- // into the same run rather than a second one, so the client waits on
62
- // exactly one revision bump.
111
+ // The card's **Fetch executables** button. A rows change is folded into
112
+ // the same run rather than a second one, so the client waits on exactly
113
+ // one revision bump.
63
114
  if (refreshChanged || rowsChanged)
64
115
  queue(controller, "probe");
65
116
  // The card's **Prelaunch Windows Chrome** button: one Windows run,
@@ -69,7 +120,12 @@ export function onSettingsChange(controller) {
69
120
  }
70
121
  }
71
122
  catch (error) {
72
- controller.ctx.logger.error(`chrome-devtools-mcp(${controller.config.serverName}): ${String(error)}`);
123
+ controller.ctx.logger.error(`dsh-chrome-mcp(${controller.config.serverName}): ${String(error)}`);
124
+ }
125
+ finally {
126
+ // Every user commit clears the live-only fields, so the mirror goes back
127
+ // out with the answers it carries.
128
+ publishLive(controller);
73
129
  }
74
130
  }
75
131
  //# sourceMappingURL=commits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commits.js","sourceRoot":"","sources":["../../../src/host/controller/commits.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commits.js","sourceRoot":"","sources":["../../../src/host/controller/commits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { Controller } from "./state.js";
2
+ /** Everything one `resolve` answered with that the live state should carry. */
3
+ export interface RunningAnswers {
4
+ /** The executable the connection launches ("" in connect mode). */
5
+ executable: string;
6
+ /** Where it came from (`"selected"` / `"row-config"` / ""). */
7
+ source: string;
8
+ /** The flags list it launched with. */
9
+ flags: string[];
10
+ /** The console-output mode it spawned with. */
11
+ stderrMode: "log" | "console";
12
+ /** Where the stderr lands when the wrapper redirects ("" otherwise). */
13
+ redirect: string;
14
+ /** The note the answer carries ("" = silent). */
15
+ note: string;
16
+ }
17
+ /**
18
+ * Mirror what a live connection runs with into the live state and say it out
19
+ * loud: publish, then notify that the pickers' answers moved (their Host-served
20
+ * choices read this state off). One log line per resolve names the connection
21
+ * being answered for.
22
+ */
23
+ export declare function noteRunning(controller: Controller, entryId: string, answers: RunningAnswers): void;
24
+ /**
25
+ * Tell the pool to re-answer every live connection whose answer depends on the
26
+ * field the row just changed. A connection carrying its own `extra` answer for
27
+ * the field does not follow the row's default, so it is left standing; every
28
+ * other owned entry is handed back for a re-resolve, live ones included — the
29
+ * diff that decides what the pool actually does with the re-resolve is decided
30
+ * on the **resolved config**, so a connection that would answer with exactly
31
+ * what it runs with is not restarted anyway, and one that would answer with
32
+ * something else switches in place.
33
+ */
34
+ export declare function invalidateOwnedForField(controller: Controller, fieldKey: string): void;
35
+ /** The invalidation key matching one kind-field, shared by the three drift paths
36
+ * in ./commits.ts. */
37
+ export declare const DEFAULT_ANSWER_FIELDS: readonly ["executable", "extraFlags", "stderrMode"];
38
+ //# sourceMappingURL=connections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../../src/host/controller/connections.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC3B,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+CAA+C;IAC/C,UAAU,EAAE,KAAK,GAAG,SAAS,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAalG;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAYtF;AAED;sBACsB;AACtB,eAAO,MAAM,qBAAqB,qDAAoF,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Controller — the manager-connection seam.
3
+ *
4
+ * The row starts no bridge of its own any more: every live bridge is one of the
5
+ * manager's connections, answered through ./kind.ts (`resolve`). What this module
6
+ * keeps is the mirror half — when a connection answers with what it runs with,
7
+ * the live state says so (the running executable, the running flags, the stderr
8
+ * destination, the running note) — plus the write paths that change what the
9
+ * **default** answers would be: a row-level flags/executable/stderr edit has to
10
+ * reach the live connections that carry no own answer for that field, which the
11
+ * pool only learns about on the next `invalidate`.
12
+ *
13
+ * The old file this replaces drove the fiber directly (`bridgeConfig` rebuild,
14
+ * `fiber.update()` chained on readiness). The pool does that now, against the
15
+ * config a kind's `resolve` hands it.
16
+ */
17
+ import { KIND_FIELDS } from "../constants.js";
18
+ import { ownedEntries } from "../manager.js";
19
+ import { noteStderr } from "./notes.js";
20
+ import { publishLive } from "./publish.js";
21
+ /**
22
+ * Mirror what a live connection runs with into the live state and say it out
23
+ * loud: publish, then notify that the pickers' answers moved (their Host-served
24
+ * choices read this state off). One log line per resolve names the connection
25
+ * being answered for.
26
+ */
27
+ export function noteRunning(controller, entryId, answers) {
28
+ const { state } = controller;
29
+ state.runningFlags = [...answers.flags];
30
+ state.runningChromePath = answers.executable;
31
+ state.runningChromeSource = answers.source === "row-config" || answers.source === "selected" ? answers.source : "";
32
+ state.runningStderrMode = answers.stderrMode;
33
+ state.live.runningFlags = [...answers.flags];
34
+ state.live.runningNote = answers.note;
35
+ if (answers.redirect !== "")
36
+ noteStderr(controller, { redirect: answers.redirect });
37
+ controller.ctx.logger.info(`dsh-chrome-mcp(${entryId}): connection answers with executable "${answers.executable || "(connect mode)"}", flags [${answers.flags.join(" ")}], stderr → ${answers.stderrMode}${answers.note === "" ? "" : `, ${answers.note}`}`);
38
+ // The publish inside `publishLive` re-notifies the pickers: the answers that
39
+ // just moved are exactly what a `select` offers.
40
+ publishLive(controller);
41
+ }
42
+ /**
43
+ * Tell the pool to re-answer every live connection whose answer depends on the
44
+ * field the row just changed. A connection carrying its own `extra` answer for
45
+ * the field does not follow the row's default, so it is left standing; every
46
+ * other owned entry is handed back for a re-resolve, live ones included — the
47
+ * diff that decides what the pool actually does with the re-resolve is decided
48
+ * on the **resolved config**, so a connection that would answer with exactly
49
+ * what it runs with is not restarted anyway, and one that would answer with
50
+ * something else switches in place.
51
+ */
52
+ export function invalidateOwnedForField(controller, fieldKey) {
53
+ const { state } = controller;
54
+ if (state.connections === void 0)
55
+ return;
56
+ try {
57
+ for (const entry of ownedEntries(state.connections)) {
58
+ if (Object.prototype.hasOwnProperty.call(entry.extra, fieldKey))
59
+ continue;
60
+ state.connections.invalidate(entry.id);
61
+ }
62
+ }
63
+ catch {
64
+ // A manager that has already gone away answers nothing; there is nothing
65
+ // to invalidate.
66
+ }
67
+ }
68
+ /** The invalidation key matching one kind-field, shared by the three drift paths
69
+ * in ./commits.ts. */
70
+ export const DEFAULT_ANSWER_FIELDS = [KIND_FIELDS.executable, KIND_FIELDS.extraFlags, KIND_FIELDS.stderrMode];
71
+ //# sourceMappingURL=connections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../src/host/controller/connections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAmB3C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,UAAsB,EAAE,OAAe,EAAE,OAAuB;IACxF,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,KAAK,CAAC,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,KAAK,CAAC,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7C,KAAK,CAAC,mBAAmB,GAAG,OAAO,CAAC,MAAM,KAAK,YAAY,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnH,KAAK,CAAC,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IACtC,IAAI,OAAO,CAAC,QAAQ,KAAK,EAAE;QAAE,UAAU,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpF,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,OAAO,0CAA0C,OAAO,CAAC,UAAU,IAAI,gBAAgB,aAAa,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9P,6EAA6E;IAC7E,iDAAiD;IACjD,WAAW,CAAC,UAAU,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CAAC,UAAsB,EAAE,QAAgB;IAC5E,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC;QAAE,OAAO;IACzC,IAAI,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAClD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAAE,SAAS;YAC1E,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,yEAAyE;QACzE,iBAAiB;IACrB,CAAC;AACL,CAAC;AAED;sBACsB;AACtB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAU,CAAC"}