@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.
- package/README.md +44 -95
- package/assets/dsh-chrome-mcp-social.png +0 -0
- package/assets/icon.svg +71 -0
- package/assets/prelaunch-windows-chrome.html +277 -0
- package/lib/client.js +3005 -568
- package/lib/client.js.map +7 -0
- package/lib/host/apply.d.ts +40 -0
- package/lib/host/apply.d.ts.map +1 -0
- package/lib/host/apply.js +57 -0
- package/lib/host/apply.js.map +1 -0
- package/lib/host/bridge.d.ts +74 -0
- package/lib/host/bridge.d.ts.map +1 -0
- package/lib/host/bridge.js +168 -0
- package/lib/host/bridge.js.map +1 -0
- package/lib/host/catalog.d.ts +31 -0
- package/lib/host/catalog.d.ts.map +1 -0
- package/lib/host/catalog.js +92 -0
- package/lib/host/catalog.js.map +1 -0
- package/lib/host/commands/chrome-path.d.ts +4 -0
- package/lib/host/commands/chrome-path.d.ts.map +1 -0
- package/lib/host/commands/chrome-path.js +65 -0
- package/lib/host/commands/chrome-path.js.map +1 -0
- package/lib/host/commands/chrome-refresh.d.ts +17 -0
- package/lib/host/commands/chrome-refresh.d.ts.map +1 -0
- package/lib/host/commands/chrome-refresh.js +37 -0
- package/lib/host/commands/chrome-refresh.js.map +1 -0
- package/lib/host/commands/index.d.ts +26 -0
- package/lib/host/commands/index.d.ts.map +1 -0
- package/lib/host/commands/index.js +41 -0
- package/lib/host/commands/index.js.map +1 -0
- package/lib/host/constants.d.ts +306 -0
- package/lib/host/constants.d.ts.map +1 -0
- package/lib/host/constants.js +319 -0
- package/lib/host/constants.js.map +1 -0
- package/lib/host/controller/_trace.d.ts +3 -0
- package/lib/host/controller/_trace.d.ts.map +1 -0
- package/lib/host/controller/_trace.js +14 -0
- package/lib/host/controller/_trace.js.map +1 -0
- package/lib/host/controller/bridge-run.d.ts +40 -0
- package/lib/host/controller/bridge-run.d.ts.map +1 -0
- package/lib/host/controller/bridge-run.js +85 -0
- package/lib/host/controller/bridge-run.js.map +1 -0
- package/lib/host/controller/captures.d.ts +15 -0
- package/lib/host/controller/captures.d.ts.map +1 -0
- package/lib/host/controller/captures.js +85 -0
- package/lib/host/controller/captures.js.map +1 -0
- package/lib/host/controller/commits.d.ts +4 -0
- package/lib/host/controller/commits.d.ts.map +1 -0
- package/lib/host/controller/commits.js +131 -0
- package/lib/host/controller/commits.js.map +1 -0
- package/lib/host/controller/connections.d.ts +38 -0
- package/lib/host/controller/connections.d.ts.map +1 -0
- package/lib/host/controller/connections.js +71 -0
- package/lib/host/controller/connections.js.map +1 -0
- package/lib/host/controller/controller.d.ts +35 -0
- package/lib/host/controller/controller.d.ts.map +1 -0
- package/lib/host/controller/controller.js +234 -0
- package/lib/host/controller/controller.js.map +1 -0
- package/lib/host/controller/index.d.ts +30 -0
- package/lib/host/controller/index.d.ts.map +1 -0
- package/lib/host/controller/index.js +27 -0
- package/lib/host/controller/index.js.map +1 -0
- package/lib/host/controller/notes.d.ts +26 -0
- package/lib/host/controller/notes.d.ts.map +1 -0
- package/lib/host/controller/notes.js +44 -0
- package/lib/host/controller/notes.js.map +1 -0
- package/lib/host/controller/persist.d.ts +16 -0
- package/lib/host/controller/persist.d.ts.map +1 -0
- package/lib/host/controller/persist.js +98 -0
- package/lib/host/controller/persist.js.map +1 -0
- package/lib/host/controller/publish.d.ts +4 -0
- package/lib/host/controller/publish.d.ts.map +1 -0
- package/lib/host/controller/publish.js +56 -0
- package/lib/host/controller/publish.js.map +1 -0
- package/lib/host/controller/runs.d.ts +80 -0
- package/lib/host/controller/runs.d.ts.map +1 -0
- package/lib/host/controller/runs.js +394 -0
- package/lib/host/controller/runs.js.map +1 -0
- package/lib/host/controller/state.d.ts +172 -0
- package/lib/host/controller/state.d.ts.map +1 -0
- package/lib/host/controller/state.js +2 -0
- package/lib/host/controller/state.js.map +1 -0
- package/lib/host/controller/windows-run.d.ts +17 -0
- package/lib/host/controller/windows-run.d.ts.map +1 -0
- package/lib/host/controller/windows-run.js +109 -0
- package/lib/host/controller/windows-run.js.map +1 -0
- package/lib/host/discovery/candidates.d.ts +47 -0
- package/lib/host/discovery/candidates.d.ts.map +1 -0
- package/lib/host/discovery/candidates.js +68 -0
- package/lib/host/discovery/candidates.js.map +1 -0
- package/lib/host/discovery/index.d.ts +19 -0
- package/lib/host/discovery/index.d.ts.map +1 -0
- package/lib/host/discovery/index.js +19 -0
- package/lib/host/discovery/index.js.map +1 -0
- package/lib/host/discovery/probe.d.ts +29 -0
- package/lib/host/discovery/probe.d.ts.map +1 -0
- package/lib/host/discovery/probe.js +155 -0
- package/lib/host/discovery/probe.js.map +1 -0
- package/lib/host/discovery/scan.d.ts +72 -0
- package/lib/host/discovery/scan.d.ts.map +1 -0
- package/lib/host/discovery/scan.js +195 -0
- package/lib/host/discovery/scan.js.map +1 -0
- package/lib/host/flags.d.ts +65 -0
- package/lib/host/flags.d.ts.map +1 -0
- package/lib/host/flags.js +186 -0
- package/lib/host/flags.js.map +1 -0
- package/lib/host/kind.d.ts +45 -0
- package/lib/host/kind.d.ts.map +1 -0
- package/lib/host/kind.js +251 -0
- package/lib/host/kind.js.map +1 -0
- package/lib/host/manager.d.ts +21 -0
- package/lib/host/manager.d.ts.map +1 -0
- package/lib/host/manager.js +113 -0
- package/lib/host/manager.js.map +1 -0
- package/lib/host/migration.d.ts +26 -0
- package/lib/host/migration.d.ts.map +1 -0
- package/lib/host/migration.js +127 -0
- package/lib/host/migration.js.map +1 -0
- package/lib/host/platform.d.ts +38 -0
- package/lib/host/platform.d.ts.map +1 -0
- package/lib/host/platform.js +64 -0
- package/lib/host/platform.js.map +1 -0
- package/lib/host/plugin-meta.d.ts +21 -0
- package/lib/host/plugin-meta.d.ts.map +1 -0
- package/lib/host/plugin-meta.js +21 -0
- package/lib/host/plugin-meta.js.map +1 -0
- package/lib/host/schema.d.ts +361 -0
- package/lib/host/schema.d.ts.map +1 -0
- package/lib/host/schema.js +196 -0
- package/lib/host/schema.js.map +1 -0
- package/lib/host/settings.d.ts +28 -0
- package/lib/host/settings.d.ts.map +1 -0
- package/lib/host/settings.js +91 -0
- package/lib/host/settings.js.map +1 -0
- package/lib/host/status.d.ts +25 -0
- package/lib/host/status.d.ts.map +1 -0
- package/lib/host/status.js +45 -0
- package/lib/host/status.js.map +1 -0
- package/lib/host/tool.d.ts +65 -0
- package/lib/host/tool.d.ts.map +1 -0
- package/lib/host/tool.js +52 -0
- package/lib/host/tool.js.map +1 -0
- package/lib/host/types/config.d.ts +101 -0
- package/lib/host/types/config.d.ts.map +1 -0
- package/lib/host/types/config.js +2 -0
- package/lib/host/types/config.js.map +1 -0
- package/lib/host/types/executable.d.ts +35 -0
- package/lib/host/types/executable.d.ts.map +1 -0
- package/lib/host/types/executable.js +9 -0
- package/lib/host/types/executable.js.map +1 -0
- package/lib/host/types/index.d.ts +24 -0
- package/lib/host/types/index.d.ts.map +1 -0
- package/lib/host/types/index.js +2 -0
- package/lib/host/types/index.js.map +1 -0
- package/lib/host/types/plugin.d.ts +38 -0
- package/lib/host/types/plugin.d.ts.map +1 -0
- package/lib/host/types/plugin.js +10 -0
- package/lib/host/types/plugin.js.map +1 -0
- package/lib/host/types/services.d.ts +26 -0
- package/lib/host/types/services.d.ts.map +1 -0
- package/lib/host/types/services.js +9 -0
- package/lib/host/types/services.js.map +1 -0
- package/lib/host/types/settings.d.ts +180 -0
- package/lib/host/types/settings.d.ts.map +1 -0
- package/lib/host/types/settings.js +2 -0
- package/lib/host/types/settings.js.map +1 -0
- package/lib/host/types/stderr.d.ts +51 -0
- package/lib/host/types/stderr.d.ts.map +1 -0
- package/lib/host/types/stderr.js +9 -0
- package/lib/host/types/stderr.js.map +1 -0
- package/lib/host/types/windows.d.ts +39 -0
- package/lib/host/types/windows.d.ts.map +1 -0
- package/lib/host/types/windows.js +9 -0
- package/lib/host/types/windows.js.map +1 -0
- package/lib/host/values.d.ts +204 -0
- package/lib/host/values.d.ts.map +1 -0
- package/lib/host/values.js +404 -0
- package/lib/host/values.js.map +1 -0
- package/lib/host/windows/connect-flags.d.ts +27 -0
- package/lib/host/windows/connect-flags.d.ts.map +1 -0
- package/lib/host/windows/connect-flags.js +97 -0
- package/lib/host/windows/connect-flags.js.map +1 -0
- package/lib/host/windows/index.d.ts +31 -0
- package/lib/host/windows/index.d.ts.map +1 -0
- package/lib/host/windows/index.js +30 -0
- package/lib/host/windows/index.js.map +1 -0
- package/lib/host/windows/landing.d.ts +47 -0
- package/lib/host/windows/landing.d.ts.map +1 -0
- package/lib/host/windows/landing.js +174 -0
- package/lib/host/windows/landing.js.map +1 -0
- package/lib/host/windows/link.d.ts +11 -0
- package/lib/host/windows/link.d.ts.map +1 -0
- package/lib/host/windows/link.js +52 -0
- package/lib/host/windows/link.js.map +1 -0
- package/lib/host/windows/paths.d.ts +64 -0
- package/lib/host/windows/paths.d.ts.map +1 -0
- package/lib/host/windows/paths.js +148 -0
- package/lib/host/windows/paths.js.map +1 -0
- package/lib/host/windows/run.d.ts +74 -0
- package/lib/host/windows/run.d.ts.map +1 -0
- package/lib/host/windows/run.js +211 -0
- package/lib/host/windows/run.js.map +1 -0
- package/lib/host/windows/spawn.d.ts +22 -0
- package/lib/host/windows/spawn.d.ts.map +1 -0
- package/lib/host/windows/spawn.js +73 -0
- package/lib/host/windows/spawn.js.map +1 -0
- package/lib/index.d.ts +102 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +102 -636
- package/lib/index.js.map +1 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +57 -14
- 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 @@
|
|
|
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"}
|