@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,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Chrome run — the connect-mode address and flag it writes.
|
|
3
|
+
*
|
|
4
|
+
* The connect half of the run: the `http://127.0.0.1:<P>` address a debugging
|
|
5
|
+
* port answers for, the port one saved `--browserUrl=` entry carries, and the
|
|
6
|
+
* replace-by-key merge that keeps the saved flags at exactly one connect entry
|
|
7
|
+
* (never two, with the local `--user-data-dir` row dropped — upstream refuses
|
|
8
|
+
* `userDataDir` and `browserUrl` in the same argv). The run calls these to
|
|
9
|
+
* answer and to persist its outcome; ./run.ts drives them.
|
|
10
|
+
*/
|
|
11
|
+
import { carriesConnectionMode } from "../flags.js";
|
|
12
|
+
import { BROWSER_URL_FLAG_PREFIX } from "../constants.js";
|
|
13
|
+
/** The connect address one debugging port answers for. */
|
|
14
|
+
export function windowsChromeUrl(port) {
|
|
15
|
+
return `http://127.0.0.1:${Math.trunc(port)}`;
|
|
16
|
+
}
|
|
17
|
+
/** The debugging port the live connect entry carries, 0 when the list carries
|
|
18
|
+
* none. The entry's **spelling** is irrelevant: the port is read through the
|
|
19
|
+
* very predicate that decides connect mode (`carriesConnectionMode` in
|
|
20
|
+
* `./flags.ts`), so `--browserUrl=<url>`, `--browserUrl <url>` (the two-entry
|
|
21
|
+
* form the whitespace-split env source produces), one string carrying its
|
|
22
|
+
* value after whitespace, and `--wsEndpoint=<url>` all answer with the live
|
|
23
|
+
* port instead of reading as "no live session". */
|
|
24
|
+
export function browserUrlFlagPort(flags) {
|
|
25
|
+
const list = Array.isArray(flags) ? flags : [];
|
|
26
|
+
for (let index = 0; index < list.length; index += 1) {
|
|
27
|
+
const flag = list[index];
|
|
28
|
+
if (typeof flag !== "string" || !carriesConnectionMode(flag))
|
|
29
|
+
continue;
|
|
30
|
+
const eq = flag.indexOf("=");
|
|
31
|
+
if (eq !== -1) {
|
|
32
|
+
const match = flag.slice(eq + 1).trim().match(/:(\d+)/u);
|
|
33
|
+
return match === null ? 0 : Number.parseInt(match[1], 10);
|
|
34
|
+
}
|
|
35
|
+
const whitespace = flag.slice(2).match(/\s/u);
|
|
36
|
+
if (whitespace?.index !== void 0) {
|
|
37
|
+
const match = flag.slice(whitespace.index + 3).trim().match(/:(\d+)/u);
|
|
38
|
+
return match === null ? 0 : Number.parseInt(match[1], 10);
|
|
39
|
+
}
|
|
40
|
+
const value = list[index + 1];
|
|
41
|
+
const match = typeof value === "string" ? value.trim().match(/:(\d+)/u) : null;
|
|
42
|
+
return match === null ? 0 : Number.parseInt(match[1], 10);
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
/** The local-profile row the connect entry makes mutually exclusive with it
|
|
47
|
+
* upstream: a saved `--user-data-dir` next to a `--browserUrl` kills the spawn
|
|
48
|
+
* (`Arguments userDataDir and browserUrl are mutually exclusive`, measured
|
|
49
|
+
* live with chrome-devtools-mcp), so the run drops it when it pins connect. */
|
|
50
|
+
const CONNECT_EXCLUDED_FLAG = "--user-data-dir";
|
|
51
|
+
/**
|
|
52
|
+
* Collapse every connect entry the list carries into the run's own address, so
|
|
53
|
+
* the saved list keeps exactly **one** connect source whatever spelling it was
|
|
54
|
+
* stored in — the same idempotency rule the saved-executable merge follows for
|
|
55
|
+
* a repeated id, keyed now on the whole connect-mode predicate rather than one
|
|
56
|
+
* flag spelling. An entry that carries its value as the *following* entry (the
|
|
57
|
+
* `--browserUrl <url>` form the whitespace-split env source produces) consumes
|
|
58
|
+
* that value with it, so no bare URL survives as a stray argv item.
|
|
59
|
+
*
|
|
60
|
+
* The one thing that does not survive is a `--user-data-dir` row: connect
|
|
61
|
+
* carries no local profile to hand the browser, upstream refuses both at once,
|
|
62
|
+
* so keeping a saved Flags-WSL row would leave the bridge unspawnable
|
|
63
|
+
* (`Arguments userDataDir and browserUrl are mutually exclusive`, measured live
|
|
64
|
+
* with chrome-devtools-mcp).
|
|
65
|
+
*/
|
|
66
|
+
export function withBrowserUrlFlag(flags, url) {
|
|
67
|
+
const entry = `${BROWSER_URL_FLAG_PREFIX}${url}`;
|
|
68
|
+
const list = Array.isArray(flags) ? flags : [];
|
|
69
|
+
const next = [];
|
|
70
|
+
let replaced = false;
|
|
71
|
+
let awaitingValue = false;
|
|
72
|
+
for (const flag of list) {
|
|
73
|
+
if (typeof flag !== "string")
|
|
74
|
+
continue;
|
|
75
|
+
if (flag.startsWith(CONNECT_EXCLUDED_FLAG))
|
|
76
|
+
continue;
|
|
77
|
+
if (carriesConnectionMode(flag)) {
|
|
78
|
+
if (!replaced) {
|
|
79
|
+
next.push(entry);
|
|
80
|
+
replaced = true;
|
|
81
|
+
}
|
|
82
|
+
// No inline value (no `=`, no whitespace) means the value is the
|
|
83
|
+
// entry that follows — drop it with the flag, exactly the way
|
|
84
|
+
// `stripExecutablePathFlags` consumes a `--flag <path>` spelling.
|
|
85
|
+
awaitingValue = !flag.includes("=") && !/\s/u.test(flag);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (awaitingValue && !flag.startsWith("-"))
|
|
89
|
+
continue;
|
|
90
|
+
awaitingValue = false;
|
|
91
|
+
next.push(flag);
|
|
92
|
+
}
|
|
93
|
+
if (!replaced)
|
|
94
|
+
next.push(entry);
|
|
95
|
+
return next;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=connect-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-flags.js","sourceRoot":"","sources":["../../../src/host/windows/connect-flags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host half — the Windows-side Chrome run behind the card's **Open Windows
|
|
3
|
+
* Chrome** button and the `prelaunch_windows_chrome` tool.
|
|
4
|
+
*
|
|
5
|
+
* The whole Windows path, split the way it reads into one directory:
|
|
6
|
+
*
|
|
7
|
+
* ./paths.ts drive→mount mapping, locate, the Windows-native profile
|
|
8
|
+
* directory + LOCALAPPDATA root, and the project dir the
|
|
9
|
+
* workspace `.chrome` view hangs under
|
|
10
|
+
* ./link.ts the workspace `.chrome` view link (a WSL-side symlink)
|
|
11
|
+
* ./connect-flags.ts the connect address + the replace-by-key `--browserUrl`
|
|
12
|
+
* merge with the local profile flag dropped
|
|
13
|
+
* ./landing.ts the packaged page the launched window opens, rendered
|
|
14
|
+
* with the run's answers, written beside the profile and
|
|
15
|
+
* answered back as a `file:///…` URL
|
|
16
|
+
* ./spawn.ts the raw TCP reachability sample + the interop launch
|
|
17
|
+
* ./run.ts the orchestrator: locate → prereq → port → launch → wait
|
|
18
|
+
*
|
|
19
|
+
* Driving the Windows browser in **connect** mode is the only Windows path ever
|
|
20
|
+
* measured to work (launching `chrome.exe` across the interop boundary cannot —
|
|
21
|
+
* the debug pipes do not survive it); see ./run.ts's header and the field log in
|
|
22
|
+
* `.probe/windows-chrome-connect-probe.log`. Every half is injectable, so the
|
|
23
|
+
* tests never depend on the machine they run on.
|
|
24
|
+
*/
|
|
25
|
+
export { findWindowsChromeExecutable, findWindowsChromeExecutables, windowsChromeLocalAppData, windowsChromeProfileDir, windowsChromeProjectDir, windowsPathToMount } from "./paths.js";
|
|
26
|
+
export { linkWindowsChromeProfile } from "./link.js";
|
|
27
|
+
export { browserUrlFlagPort, withBrowserUrlFlag, windowsChromeUrl } from "./connect-flags.js";
|
|
28
|
+
export { windowsChromeLandingAsset, windowsChromeLandingHtml, windowsChromeLandingPath, windowsChromeLandingUrl, windowsFileUrl } from "./landing.js";
|
|
29
|
+
export { runWindowsChromeConnect } from "./run.js";
|
|
30
|
+
export type { WindowsChromeRunOptions } from "./run.js";
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/host/windows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host half — the Windows-side Chrome run behind the card's **Open Windows
|
|
3
|
+
* Chrome** button and the `prelaunch_windows_chrome` tool.
|
|
4
|
+
*
|
|
5
|
+
* The whole Windows path, split the way it reads into one directory:
|
|
6
|
+
*
|
|
7
|
+
* ./paths.ts drive→mount mapping, locate, the Windows-native profile
|
|
8
|
+
* directory + LOCALAPPDATA root, and the project dir the
|
|
9
|
+
* workspace `.chrome` view hangs under
|
|
10
|
+
* ./link.ts the workspace `.chrome` view link (a WSL-side symlink)
|
|
11
|
+
* ./connect-flags.ts the connect address + the replace-by-key `--browserUrl`
|
|
12
|
+
* merge with the local profile flag dropped
|
|
13
|
+
* ./landing.ts the packaged page the launched window opens, rendered
|
|
14
|
+
* with the run's answers, written beside the profile and
|
|
15
|
+
* answered back as a `file:///…` URL
|
|
16
|
+
* ./spawn.ts the raw TCP reachability sample + the interop launch
|
|
17
|
+
* ./run.ts the orchestrator: locate → prereq → port → launch → wait
|
|
18
|
+
*
|
|
19
|
+
* Driving the Windows browser in **connect** mode is the only Windows path ever
|
|
20
|
+
* measured to work (launching `chrome.exe` across the interop boundary cannot —
|
|
21
|
+
* the debug pipes do not survive it); see ./run.ts's header and the field log in
|
|
22
|
+
* `.probe/windows-chrome-connect-probe.log`. Every half is injectable, so the
|
|
23
|
+
* tests never depend on the machine they run on.
|
|
24
|
+
*/
|
|
25
|
+
export { findWindowsChromeExecutable, findWindowsChromeExecutables, windowsChromeLocalAppData, windowsChromeProfileDir, windowsChromeProjectDir, windowsPathToMount } from "./paths.js";
|
|
26
|
+
export { linkWindowsChromeProfile } from "./link.js";
|
|
27
|
+
export { browserUrlFlagPort, withBrowserUrlFlag, windowsChromeUrl } from "./connect-flags.js";
|
|
28
|
+
export { windowsChromeLandingAsset, windowsChromeLandingHtml, windowsChromeLandingPath, windowsChromeLandingUrl, windowsFileUrl } from "./landing.js";
|
|
29
|
+
export { runWindowsChromeConnect } from "./run.js";
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/host/windows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACH,2BAA2B,EAC3B,4BAA4B,EAC5B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** The run's own tokens in the packaged page, in the shape each one answers. */
|
|
2
|
+
type LandingTokens = {
|
|
3
|
+
url: string;
|
|
4
|
+
port: number;
|
|
5
|
+
profile: string;
|
|
6
|
+
};
|
|
7
|
+
/** The packaged page's path on this host, "" when the package carries none. */
|
|
8
|
+
export declare function windowsChromeLandingAsset(): string;
|
|
9
|
+
/**
|
|
10
|
+
* The packaged page, with the run's answers folded into its `{{TOKEN}}`s —
|
|
11
|
+
* "" when the asset is not there. Values are escaped, tokens the page does not
|
|
12
|
+
* carry are simply left alone, and a page whose write fails downstream is not
|
|
13
|
+
* this function's problem: it answers the *rendered* text, nothing else.
|
|
14
|
+
*/
|
|
15
|
+
export declare function windowsChromeLandingHtml(tokens?: Partial<LandingTokens>): string;
|
|
16
|
+
/**
|
|
17
|
+
* The landing file's Windows path beside a profile directory:
|
|
18
|
+
* `…\dsh-chrome-mcp\prelaunch-<port>.html`, a **sibling** of the profile rather
|
|
19
|
+
* than a file inside it — Chrome owns everything inside its own profile
|
|
20
|
+
* directory, and this page is not part of one.
|
|
21
|
+
*/
|
|
22
|
+
export declare function windowsChromeLandingPath(profileDir: unknown, port: number): string;
|
|
23
|
+
/**
|
|
24
|
+
* A Windows path as a `file://` URL — the only form the launched browser reads
|
|
25
|
+
* (the interop mount path is Linux-side, invisible to `chrome.exe`). No drive
|
|
26
|
+
* letter answers "" (never a half-formed URL), and every path segment is
|
|
27
|
+
* percent-encoded, since a user profile directory routinely carries spaces.
|
|
28
|
+
*/
|
|
29
|
+
export declare function windowsFileUrl(path: unknown): string;
|
|
30
|
+
/**
|
|
31
|
+
* The whole landing-page half of a launch: render the packaged page with this
|
|
32
|
+
* run's answers, write it beside the profile directory through the interop
|
|
33
|
+
* mount, and answer the `file:///…` URL to hand the browser ("" = launch with
|
|
34
|
+
* no page). Every failure is silent on purpose — the page explains the window,
|
|
35
|
+
* it never gates it.
|
|
36
|
+
* @param profileDir - the Windows-side profile directory the launch carries.
|
|
37
|
+
* @param url - the connect address the window answers for.
|
|
38
|
+
* @param port - the debugging port that launch picked.
|
|
39
|
+
* @param write - the filesystem half: place `html` at the **mount** path and
|
|
40
|
+
* answer whether it actually landed. Defaults to creating the directory and
|
|
41
|
+
* writing the file through the interop mount; injected so a test never depends
|
|
42
|
+
* on the machine it runs on (the mount is never inside the checkout, and the
|
|
43
|
+
* agent's own file sandbox denies it outright).
|
|
44
|
+
*/
|
|
45
|
+
export declare function windowsChromeLandingUrl(profileDir: unknown, url: unknown, port: unknown, write?: (mountPath: string, html: string) => boolean): string;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=landing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"landing.d.ts","sourceRoot":"","sources":["../../../src/host/windows/landing.ts"],"names":[],"mappings":"AA6BA,gFAAgF;AAChF,KAAK,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA0BpE,+EAA+E;AAC/E,wBAAgB,yBAAyB,IAAI,MAAM,CAMlD;AAQD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,MAAM,CAmBpF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAWpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,OAAO,EACnB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,GACrD,MAAM,CAuBR"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Chrome run — the **landing page** the launched window opens.
|
|
3
|
+
*
|
|
4
|
+
* A window that appears for no visible reason looks like a malfunction, and the
|
|
5
|
+
* honest answer to "why did a Chrome window just open?" is a paragraph of
|
|
6
|
+
* explanation the bridge's argv cannot carry. So the run ships one: a packaged,
|
|
7
|
+
* self-contained HTML page (`assets/prelaunch-windows-chrome.html`, the only
|
|
8
|
+
* asset the plugin carries) rendered with the run's own answers and written next
|
|
9
|
+
* to the Windows-side profile directory, so the window that opens *states* what
|
|
10
|
+
* it is for — opened by the plugin from DSH so the bridge can drive it over the
|
|
11
|
+
* debugging port, never a browsing session the user started.
|
|
12
|
+
*
|
|
13
|
+
* The file has to live on the **Windows** filesystem and be handed to the browser
|
|
14
|
+
* as a `file:///…` URL, exactly like the profile directory it sits beside: the
|
|
15
|
+
* WSL-side path is invisible to a Windows-side process. Nothing depends on it:
|
|
16
|
+
* every answer is "" when the asset cannot be read, the write fails or LOCALAPPDATA
|
|
17
|
+
* never answered, and a run without a landing page launches the same browser it
|
|
18
|
+
* launched before — the page is a description of the window, not a precondition
|
|
19
|
+
* of it. It is never opened on the re-attach branch (nothing was launched, so no
|
|
20
|
+
* window was added), and it is opened exactly once per launch.
|
|
21
|
+
*/
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
23
|
+
import { dirname } from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
import { WINDOWS_CHROME_LANDING_ASSET, WINDOWS_CHROME_LANDING_BASENAME } from "../constants.js";
|
|
26
|
+
import { windowsPathToMount } from "./paths.js";
|
|
27
|
+
/** The packaged page, resolved once per process (see {@link packageRoot} for why
|
|
28
|
+
* the lookup walks directories instead of trusting a depth). */
|
|
29
|
+
let cachedAsset;
|
|
30
|
+
/**
|
|
31
|
+
* The package root, walked up from this module until a `package.json` shows up:
|
|
32
|
+
* the emit sits under `lib/host/windows/`, so the asset's package-root-relative
|
|
33
|
+
* path is the same whether the plugin was installed or linked from a checkout,
|
|
34
|
+
* and a hard-coded `../../` would break the day the layout moves. "" answers when
|
|
35
|
+
* the lookup runs out of directories (an exotic packaging), which is simply no
|
|
36
|
+
* landing page.
|
|
37
|
+
*/
|
|
38
|
+
function packageRoot() {
|
|
39
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
40
|
+
for (let hops = 0; hops < 8; hops += 1) {
|
|
41
|
+
const manifest = `${dir}/package.json`;
|
|
42
|
+
if (existsSync(manifest))
|
|
43
|
+
return dir;
|
|
44
|
+
const parent = dirname(dir);
|
|
45
|
+
if (parent === dir)
|
|
46
|
+
break;
|
|
47
|
+
dir = parent;
|
|
48
|
+
}
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
/** The packaged page's path on this host, "" when the package carries none. */
|
|
52
|
+
export function windowsChromeLandingAsset() {
|
|
53
|
+
if (typeof cachedAsset === "string")
|
|
54
|
+
return cachedAsset;
|
|
55
|
+
const root = packageRoot();
|
|
56
|
+
const asset = root === "" ? "" : `${root}/${WINDOWS_CHROME_LANDING_ASSET}`;
|
|
57
|
+
cachedAsset = asset !== "" && existsSync(asset) ? asset : "";
|
|
58
|
+
return cachedAsset;
|
|
59
|
+
}
|
|
60
|
+
/** The one HTML entity escape the page needs: the profile path is the only
|
|
61
|
+
* value that can carry markup characters (a user name with `&`, say). */
|
|
62
|
+
function escapeHtml(value) {
|
|
63
|
+
return String(value ?? "").replace(/&/gu, "&").replace(/</gu, "<").replace(/>/gu, ">");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The packaged page, with the run's answers folded into its `{{TOKEN}}`s —
|
|
67
|
+
* "" when the asset is not there. Values are escaped, tokens the page does not
|
|
68
|
+
* carry are simply left alone, and a page whose write fails downstream is not
|
|
69
|
+
* this function's problem: it answers the *rendered* text, nothing else.
|
|
70
|
+
*/
|
|
71
|
+
export function windowsChromeLandingHtml(tokens = {}) {
|
|
72
|
+
const asset = windowsChromeLandingAsset();
|
|
73
|
+
if (asset === "")
|
|
74
|
+
return "";
|
|
75
|
+
let html;
|
|
76
|
+
try {
|
|
77
|
+
html = readFileSync(asset, "utf8");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
const port = Number.isFinite(tokens.port) ? String(Math.trunc(Number(tokens.port))) : "";
|
|
83
|
+
const values = {
|
|
84
|
+
URL: escapeHtml(typeof tokens.url === "string" ? tokens.url : ""),
|
|
85
|
+
PORT: port,
|
|
86
|
+
PROFILE: escapeHtml(typeof tokens.profile === "string" ? tokens.profile : "")
|
|
87
|
+
};
|
|
88
|
+
for (const [token, value] of Object.entries(values)) {
|
|
89
|
+
html = html.split(`{{${token}}}`).join(value);
|
|
90
|
+
}
|
|
91
|
+
return html;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The landing file's Windows path beside a profile directory:
|
|
95
|
+
* `…\dsh-chrome-mcp\prelaunch-<port>.html`, a **sibling** of the profile rather
|
|
96
|
+
* than a file inside it — Chrome owns everything inside its own profile
|
|
97
|
+
* directory, and this page is not part of one.
|
|
98
|
+
*/
|
|
99
|
+
export function windowsChromeLandingPath(profileDir, port) {
|
|
100
|
+
const profile = typeof profileDir === "string" ? profileDir.trim().replace(/[\\/]+$/u, "") : "";
|
|
101
|
+
if (profile === "")
|
|
102
|
+
return "";
|
|
103
|
+
const cut = Math.max(profile.lastIndexOf("\\"), profile.lastIndexOf("/"));
|
|
104
|
+
if (cut <= 0)
|
|
105
|
+
return "";
|
|
106
|
+
const leaf = `${WINDOWS_CHROME_LANDING_BASENAME}-${String(Math.trunc(port))}.html`;
|
|
107
|
+
return `${profile.slice(0, cut)}\\${leaf}`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A Windows path as a `file://` URL — the only form the launched browser reads
|
|
111
|
+
* (the interop mount path is Linux-side, invisible to `chrome.exe`). No drive
|
|
112
|
+
* letter answers "" (never a half-formed URL), and every path segment is
|
|
113
|
+
* percent-encoded, since a user profile directory routinely carries spaces.
|
|
114
|
+
*/
|
|
115
|
+
export function windowsFileUrl(path) {
|
|
116
|
+
if (typeof path !== "string")
|
|
117
|
+
return "";
|
|
118
|
+
const candidate = path.trim().replace(/[\\/]+$/u, "");
|
|
119
|
+
const match = candidate.match(/^([a-zA-Z]):[\\/](.*)$/u);
|
|
120
|
+
if (match === null)
|
|
121
|
+
return "";
|
|
122
|
+
const segments = match[2]
|
|
123
|
+
.split(/[\\/]+/u)
|
|
124
|
+
.filter((segment) => segment !== "")
|
|
125
|
+
.map((segment) => encodeURIComponent(segment));
|
|
126
|
+
if (segments.length === 0)
|
|
127
|
+
return "";
|
|
128
|
+
return `file:///${match[1]}:/${segments.join("/")}`;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The whole landing-page half of a launch: render the packaged page with this
|
|
132
|
+
* run's answers, write it beside the profile directory through the interop
|
|
133
|
+
* mount, and answer the `file:///…` URL to hand the browser ("" = launch with
|
|
134
|
+
* no page). Every failure is silent on purpose — the page explains the window,
|
|
135
|
+
* it never gates it.
|
|
136
|
+
* @param profileDir - the Windows-side profile directory the launch carries.
|
|
137
|
+
* @param url - the connect address the window answers for.
|
|
138
|
+
* @param port - the debugging port that launch picked.
|
|
139
|
+
* @param write - the filesystem half: place `html` at the **mount** path and
|
|
140
|
+
* answer whether it actually landed. Defaults to creating the directory and
|
|
141
|
+
* writing the file through the interop mount; injected so a test never depends
|
|
142
|
+
* on the machine it runs on (the mount is never inside the checkout, and the
|
|
143
|
+
* agent's own file sandbox denies it outright).
|
|
144
|
+
*/
|
|
145
|
+
export function windowsChromeLandingUrl(profileDir, url, port, write) {
|
|
146
|
+
const number = Number.isFinite(port) ? Math.trunc(Number(port)) : 0;
|
|
147
|
+
const path = windowsChromeLandingPath(profileDir, number);
|
|
148
|
+
if (path === "")
|
|
149
|
+
return "";
|
|
150
|
+
const html = windowsChromeLandingHtml({
|
|
151
|
+
url: typeof url === "string" ? url : "",
|
|
152
|
+
port: number,
|
|
153
|
+
profile: typeof profileDir === "string" ? profileDir : ""
|
|
154
|
+
});
|
|
155
|
+
if (html === "")
|
|
156
|
+
return "";
|
|
157
|
+
const mount = windowsPathToMount(path);
|
|
158
|
+
if (mount === "")
|
|
159
|
+
return "";
|
|
160
|
+
const place = (mountPath, content) => {
|
|
161
|
+
try {
|
|
162
|
+
mkdirSync(dirname(mountPath), { recursive: true });
|
|
163
|
+
writeFileSync(mountPath, content, "utf8");
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
};
|
|
170
|
+
if (!(typeof write === "function" ? write(mount, html) : place(mount, html)))
|
|
171
|
+
return "";
|
|
172
|
+
return windowsFileUrl(path);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=landing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"landing.js","sourceRoot":"","sources":["../../../src/host/windows/landing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WindowsChromeLinkAnswer } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Points `linkPath` (the workspace's `.chrome`, a WSL-side path) at the
|
|
4
|
+
* Windows-side profile directory — the link is pure WSL-side, so Windows never
|
|
5
|
+
* sees it, but everything the run profiles reads back from the checkout. The
|
|
6
|
+
* target is Linux-side (`/mnt/c…`): Chrome reads the Windows spelling of the
|
|
7
|
+
* link's own target, not this link at all. A real directory that is already
|
|
8
|
+
* there is kept untouched (it might carry the user's own reading).
|
|
9
|
+
*/
|
|
10
|
+
export declare function linkWindowsChromeProfile(linkPath: unknown, profileWin: unknown): WindowsChromeLinkAnswer;
|
|
11
|
+
//# sourceMappingURL=link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/host/windows/link.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,uBAAuB,CAwBxG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Chrome run — the workspace `.chrome` view link.
|
|
3
|
+
*
|
|
4
|
+
* A run profiles a Windows-native directory and keeps the checkout's `.chrome`
|
|
5
|
+
* as a **view** of it: a WSL-side symlink, so Windows never sees the link, but
|
|
6
|
+
* the checkout reads the profile back through it. A real directory already
|
|
7
|
+
* sitting at the view spot is kept — the link never clobbers what is already
|
|
8
|
+
* there. The answer names what happened (`linked`/`updated`/`kept`/`failed`) so
|
|
9
|
+
* the controller states a kept directory exactly once.
|
|
10
|
+
*/
|
|
11
|
+
import { lstatSync, readlinkSync, symlinkSync, unlinkSync } from "node:fs";
|
|
12
|
+
import { windowsPathToMount } from "./paths.js";
|
|
13
|
+
/**
|
|
14
|
+
* Points `linkPath` (the workspace's `.chrome`, a WSL-side path) at the
|
|
15
|
+
* Windows-side profile directory — the link is pure WSL-side, so Windows never
|
|
16
|
+
* sees it, but everything the run profiles reads back from the checkout. The
|
|
17
|
+
* target is Linux-side (`/mnt/c…`): Chrome reads the Windows spelling of the
|
|
18
|
+
* link's own target, not this link at all. A real directory that is already
|
|
19
|
+
* there is kept untouched (it might carry the user's own reading).
|
|
20
|
+
*/
|
|
21
|
+
export function linkWindowsChromeProfile(linkPath, profileWin) {
|
|
22
|
+
const link = typeof linkPath === "string" ? linkPath.trim().replace(/[\\/]+$/u, "") : "";
|
|
23
|
+
const target = windowsPathToMount(profileWin);
|
|
24
|
+
if (link === "" || target === "")
|
|
25
|
+
return "failed";
|
|
26
|
+
let existing;
|
|
27
|
+
try {
|
|
28
|
+
existing = lstatSync(link);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
try {
|
|
32
|
+
symlinkSync(target, link);
|
|
33
|
+
return "linked";
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return "failed";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!existing.isSymbolicLink())
|
|
40
|
+
return "kept";
|
|
41
|
+
if (readlinkSync(link) === target)
|
|
42
|
+
return "updated";
|
|
43
|
+
try {
|
|
44
|
+
unlinkSync(link);
|
|
45
|
+
symlinkSync(target, link);
|
|
46
|
+
return "updated";
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return "failed";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../../src/host/windows/link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAiB,EAAE,UAAmB;IAC3E,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,QAAsC,CAAC;IAC3C,IAAI,CAAC;QACD,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACL,IAAI,CAAC;YACD,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC1B,OAAO,QAAQ,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,QAAQ,CAAC;QACpB,CAAC;IACL,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,QAAQ,CAAC;IACpB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Windows spelling mapped onto the interop mount (`C:\Program Files\…` →
|
|
3
|
+
* `/mnt/c/Program Files/…`), which is the form WSL can stat. A path already
|
|
4
|
+
* spelled as the mount maps to itself — the mount spelling is what the WSL side
|
|
5
|
+
* can stat and therefore what a saved row or the row config may carry — and a
|
|
6
|
+
* path that is neither maps nowhere and yields "".
|
|
7
|
+
*
|
|
8
|
+
* A path may have been written or copied shell-style, where a space is escaped
|
|
9
|
+
* (`Program\ Files`). Such a backslash escapes the space that follows it and is
|
|
10
|
+
* not a separator, so it folds away to the plain space first; every other
|
|
11
|
+
* backslash is a Windows separator and folds to a slash. Turning one space
|
|
12
|
+
* escape blindly into a slash produced `Program/ Files` — a path that exists
|
|
13
|
+
* nowhere and answers `not-found` for a Chrome the run had actually located
|
|
14
|
+
* (measured live 2026-10-12 against a saved mount-spelled selection).
|
|
15
|
+
*/
|
|
16
|
+
export declare function windowsPathToMount(path: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* Locate the Windows-side Chrome through the interop mount: the first candidate
|
|
19
|
+
* whose mount path exists, "" when this machine carries none of them. The
|
|
20
|
+
* returned path keeps its **Windows** spelling — it is what the `start`
|
|
21
|
+
* invocation takes and what the card names.
|
|
22
|
+
*/
|
|
23
|
+
export declare function findWindowsChromeExecutable(exists?: (path: string) => boolean, candidates?: readonly string[]): string;
|
|
24
|
+
/**
|
|
25
|
+
* Every Windows-side executable this host carries, in the list's own preference
|
|
26
|
+
* order and in its **Windows** spelling — the whole located set, not only the
|
|
27
|
+
* first. This is what the executable run folds into its candidate list, so the
|
|
28
|
+
* picker offers the Windows browser instead of hiding it. A machine that carries
|
|
29
|
+
* none of them answers nothing, so the list is what is installed here, never a
|
|
30
|
+
* fixed set of install locations. Nothing on the list is ever spawned from WSL
|
|
31
|
+
* (see `blockedForPlatform`); it is offered so that the **Prelaunch Windows
|
|
32
|
+
* Chrome** run can be pointed at the one the picker selected.
|
|
33
|
+
*/
|
|
34
|
+
export declare function findWindowsChromeExecutables(exists?: (path: string) => boolean, candidates?: readonly string[]): string[];
|
|
35
|
+
/**
|
|
36
|
+
* The Windows-side profile directory: `<localAppData>\<dir>\.chrome[-<port>]`.
|
|
37
|
+
* The profile has to live on the Windows filesystem — Chrome takes real locks
|
|
38
|
+
* for its SQLite tables and its singleton socket, and the WSL-side directories
|
|
39
|
+
* Windows sees through the interop mount (9P) cannot carry them: a profile
|
|
40
|
+
* rooted there creates every table as a zero-byte file, never answers the
|
|
41
|
+
* singleton lock, and shows "an error occurred while opening your profile" on
|
|
42
|
+
* every launch (measured live 2026-10-04 against Chrome 154). "" answers when
|
|
43
|
+
* LOCALAPPDATA is not there.
|
|
44
|
+
*/
|
|
45
|
+
export declare function windowsChromeProfileDir(localAppData: unknown, leaf?: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves `%LOCALAPPDATA%` on the Windows side through the Known Folder API
|
|
48
|
+
* (never the inherited environment — the interop hand-off drops it, so
|
|
49
|
+
* `echo %LOCALAPPDATA%` comes back empty), cached across the process:
|
|
50
|
+
* powershell answers it exactly once per host.
|
|
51
|
+
*/
|
|
52
|
+
export declare function windowsChromeLocalAppData(): string;
|
|
53
|
+
/**
|
|
54
|
+
* The directory the Windows run roots its profile view under — the project
|
|
55
|
+
* whose checkout the run answers: the row-config `cwd`, else the **live
|
|
56
|
+
* session workspace** (the run answers to the GUI the user is driving, not to
|
|
57
|
+
* whatever directory `dsh web` happened to be launched from — a run rooted at
|
|
58
|
+
* `~` links `~/.chrome` instead of the workspace), else the host's own cwd.
|
|
59
|
+
* @param configCwd - the row-config `cwd`, "" when unset.
|
|
60
|
+
* @param sessions - the sessions service, resolved optionally.
|
|
61
|
+
* @param hostCwd - the host process' cwd.
|
|
62
|
+
*/
|
|
63
|
+
export declare function windowsChromeProjectDir(configCwd: unknown, sessions: unknown, hostCwd: string): string;
|
|
64
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/host/windows/paths.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQxD;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACvC,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAA4C,EACtE,UAAU,GAAE,SAAS,MAAM,EAA8B,GAC1D,MAAM,CAER;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CACxC,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAA4C,EACtE,UAAU,GAAE,SAAS,MAAM,EAA8B,GAC1D,MAAM,EAAE,CAQV;AAKD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,SAAY,GAAG,MAAM,CAMvF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAelD;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBtG"}
|