@farmslot/adapter-web 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/browser-cdp.d.cts +119 -0
- package/dist/browser-resolver.d.cts +140 -0
- package/dist/chrome-args.d.cts +29 -0
- package/dist/extension-id.d.cts +4 -0
- package/dist/macos-focus.d.cts +10 -0
- package/dist/page-target.d.cts +4 -0
- package/dist/playwright-cdp.d.cts +8 -0
- package/dist/validation-launch-supervisor.d.cts +2 -0
- package/dist/validation-process-ownership.d.cts +14 -0
- package/package.json +97 -0
- package/src/browser-cdp.cjs +734 -0
- package/src/browser-resolver.cjs +1211 -0
- package/src/chrome-args.cjs +371 -0
- package/src/extension-id.cjs +39 -0
- package/src/macos-focus.cjs +118 -0
- package/src/page-target.cjs +25 -0
- package/src/playwright-cdp.cjs +55 -0
- package/src/validation-launch-supervisor.cjs +320 -0
- package/src/validation-process-ownership.cjs +130 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@farmslot/adapter-web` are tracked here.
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
8
|
+
|
|
9
|
+
## 0.1.0 - 2026-10-04
|
|
10
|
+
|
|
11
|
+
- Add the package with the browser process and CDP layer moved from `@deeeed/metamask-harness`, unchanged in behaviour: `browser-resolver` (Chrome for Testing vs branded Chrome, probe cache, `runCli` entry), `browser-cdp` (deadline-bound browser CDP client, CDP-port ownership proof, `Extensions.loadUnpacked`, extension isolation), `chrome-args` (remote-debugging flags, runtime identity nonce, launch quarantine), `extension-id`, `macos-focus`, `playwright-cdp` (LavaMoat-safe page evaluation), `validation-process-ownership` and `validation-launch-supervisor`. Process, on-disk and environment names are Farmslot's: `--farmslot-runtime-nonce=`, `.farmslot-detached-launch-unproven`, `/tmp/farmslot-browser-validation-<uid>`, `~/.cache/farmslot/browser-probe.json`, `farmslot-browser-probe-*`, `FARMSLOT_FOCUS_HOLD`, `FARMSLOT_FOCUS_BROWSER` and `FARMSLOT_VALIDATION_PORT_LEASE`; remediation hints name no product command.
|
|
12
|
+
- Add `page-target` (`selectPageTarget`: the page on an origin, preferring one whose URL carries a hash) and `browser-cdp.placeWindow` (move a target's window over CDP; a visible window moves without activating the browser).
|
|
13
|
+
- Every module's exports are named bindings Node's CommonJS export detection can read, so ESM named imports work (`import { probeLaunch } from '@farmslot/adapter-web/browser-resolver'`); a package test checks `import()` against `require()` for each export.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arthur Breton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @farmslot/adapter-web
|
|
2
|
+
|
|
3
|
+
Web platform pieces for Farmslot recipes: pick and launch an isolated Chromium, prove which process owns a CDP port, load an unpacked extension, and give macOS focus back after a headed launch. A harness builds its `web` platform on these; the modules hold no product knowledge.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
const { resolveBrowser } = require('@farmslot/adapter-web/browser-resolver');
|
|
7
|
+
const { connectBrowserCdp, waitForCdpOwner } = require('@farmslot/adapter-web/browser-cdp');
|
|
8
|
+
const { activateMacAppByPid } = require('@farmslot/adapter-web/macos-focus');
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Docs: https://farmslot.io/docs/reference/adapter-web
|
|
12
|
+
|
|
13
|
+
## Source layout
|
|
14
|
+
|
|
15
|
+
| module | owns |
|
|
16
|
+
| ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `browser-resolver` | Chrome for Testing vs branded Chrome, probe-launch and its cache, extension loading method; CLI entry |
|
|
18
|
+
| `browser-cdp` | browser-level CDP client with deadlines, CDP-port ownership proof, `Extensions.loadUnpacked`, window placement |
|
|
19
|
+
| `chrome-args` | remote-debugging flags, isolated profile flags, runtime identity nonce, launch quarantine markers |
|
|
20
|
+
| `extension-id` | Chromium extension id from a manifest key or an unpacked directory |
|
|
21
|
+
| `macos-focus` | capture the frontmost app before a headed launch and restore it if one of our browsers took it |
|
|
22
|
+
| `page-target` | pick the page on an origin, preferring one whose URL carries a hash |
|
|
23
|
+
| `playwright-cdp` | page evaluation over a raw CDP session (safe under LavaMoat scuttling) |
|
|
24
|
+
| `validation-process-ownership` | find and stop the processes that own a slot profile |
|
|
25
|
+
| `validation-launch-supervisor` | supervised child for one validation launch: port lease, quarantine and cleanup |
|
|
26
|
+
|
|
27
|
+
Sources are CommonJS (`src/*.cjs`) and ship as is; `yarn build` emits `.d.cts` declarations. Every library subpath can be `require`d or `import`ed with named imports, except `validation-launch-supervisor`: it is a child-process entry (it runs when loaded), so hosts `require.resolve` it and fork it.
|
|
28
|
+
|
|
29
|
+
## Maintenance rules
|
|
30
|
+
|
|
31
|
+
1. No product knowledge. A product's build locks, titles, fixtures and wallet state stay in its harness and reach these modules as arguments.
|
|
32
|
+
2. Process and on-disk identity strings (runtime nonce flag, launch markers, probe cache path) are how a launched browser and its profile are recognised. Changing one makes browsers started under the old name unrecognised; call that out in the release notes.
|
|
33
|
+
3. Every CDP call has a deadline. Never add an unbounded wait.
|
|
34
|
+
4. Never steal focus. A headed launch restores the previous frontmost app; window activation goes by pid, not by app name. `placeWindow` moves a visible window without activating it (restoring a minimized one can).
|
|
35
|
+
|
|
36
|
+
## Local quality
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
yarn workspace @farmslot/adapter-web quality
|
|
40
|
+
```
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const DEFAULT_COMMAND_TIMEOUT_MS: 15000;
|
|
2
|
+
export const START_TIME_SLACK_MS: 2000;
|
|
3
|
+
/**
|
|
4
|
+
* @param {number} port
|
|
5
|
+
* @param {string} profile
|
|
6
|
+
* @param {{ exec?: typeof defaultExec, timeoutMs?: number }} [options]
|
|
7
|
+
*/
|
|
8
|
+
export function assertCdpOwnedByProfile(port: number, profile: string, options?: {
|
|
9
|
+
exec?: typeof defaultExec;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}): {
|
|
12
|
+
pid: number;
|
|
13
|
+
startedAt: string;
|
|
14
|
+
profile: string;
|
|
15
|
+
cdpPort: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* @param {{ pid: number, startedAt: string, profile: string, cdpPort: number }} owner
|
|
19
|
+
* @param {{ exec?: typeof defaultExec, timeoutMs?: number }} [options]
|
|
20
|
+
*/
|
|
21
|
+
export function assertSameOwner(owner: {
|
|
22
|
+
pid: number;
|
|
23
|
+
startedAt: string;
|
|
24
|
+
profile: string;
|
|
25
|
+
cdpPort: number;
|
|
26
|
+
}, { exec, timeoutMs }?: {
|
|
27
|
+
exec?: typeof defaultExec;
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
}): {
|
|
30
|
+
pid: number;
|
|
31
|
+
startedAt: string;
|
|
32
|
+
profile: string;
|
|
33
|
+
cdpPort: number;
|
|
34
|
+
};
|
|
35
|
+
export function canonicalProfile(profile: any): string;
|
|
36
|
+
export function cdpListenerPids(port: any, exec?: typeof defaultExec, { deadline }?: {
|
|
37
|
+
deadline?: number | undefined;
|
|
38
|
+
}): number[];
|
|
39
|
+
export function cdpOwner(port: any, profile: any, { exec, timeoutMs }?: {
|
|
40
|
+
exec?: typeof defaultExec | undefined;
|
|
41
|
+
timeoutMs?: number | undefined;
|
|
42
|
+
}): {
|
|
43
|
+
pid: number;
|
|
44
|
+
startedAt: string;
|
|
45
|
+
profile: string;
|
|
46
|
+
cdpPort: number;
|
|
47
|
+
};
|
|
48
|
+
export function processStartTime(pid: any, exec?: typeof defaultExec, { timeoutMs }?: {
|
|
49
|
+
timeoutMs?: number | undefined;
|
|
50
|
+
}): string | null;
|
|
51
|
+
export function waitForCdpOwner(port: any, profile: any, { timeoutMs, exec }?: {
|
|
52
|
+
timeoutMs?: number | undefined;
|
|
53
|
+
exec?: typeof defaultExec | undefined;
|
|
54
|
+
}): {
|
|
55
|
+
pid: number;
|
|
56
|
+
startedAt: string;
|
|
57
|
+
profile: string;
|
|
58
|
+
cdpPort: number;
|
|
59
|
+
};
|
|
60
|
+
export function connectBrowserCdp(port: any, { timeoutMs, commandTimeoutMs }?: {
|
|
61
|
+
timeoutMs?: number | undefined;
|
|
62
|
+
commandTimeoutMs?: number | undefined;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
send: (method: any, params: {} | undefined, sessionId: any, timeout?: number) => Promise<any>;
|
|
65
|
+
close: () => void;
|
|
66
|
+
}>;
|
|
67
|
+
export function expectedExtensionId(extensionDir: any): string | null;
|
|
68
|
+
export function loadUnpackedExtension(send: any, extensionDir: any, { expectedId, timeoutMs }?: {
|
|
69
|
+
expectedId?: null | undefined;
|
|
70
|
+
timeoutMs?: number | undefined;
|
|
71
|
+
}): Promise<{
|
|
72
|
+
id: any;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* @param {number} port
|
|
76
|
+
* @param {string} extensionDir
|
|
77
|
+
* @param {{ profile: string, expectedId?: string | null, url?: string | null, timeoutMs?: number, exec?: typeof defaultExec }} options
|
|
78
|
+
*/
|
|
79
|
+
export function loadUnpackedOverPort(port: number, extensionDir: string, { profile, expectedId, url, timeoutMs, exec, }?: {
|
|
80
|
+
profile: string;
|
|
81
|
+
expectedId?: string | null;
|
|
82
|
+
url?: string | null;
|
|
83
|
+
timeoutMs?: number;
|
|
84
|
+
exec?: typeof defaultExec;
|
|
85
|
+
}): Promise<{
|
|
86
|
+
otherExtensions: {
|
|
87
|
+
disabled: {
|
|
88
|
+
id: any;
|
|
89
|
+
name: any;
|
|
90
|
+
location: any;
|
|
91
|
+
}[];
|
|
92
|
+
policyPinned: any;
|
|
93
|
+
};
|
|
94
|
+
owner: {
|
|
95
|
+
pid: number;
|
|
96
|
+
startedAt: string;
|
|
97
|
+
profile: string;
|
|
98
|
+
cdpPort: number;
|
|
99
|
+
};
|
|
100
|
+
id: any;
|
|
101
|
+
}>;
|
|
102
|
+
export function ensureBackgroundWindow(send: any, remaining: any): Promise<void>;
|
|
103
|
+
export function isolateExtension(send: any, extensionId: any, { timeoutMs }?: {
|
|
104
|
+
timeoutMs?: number | undefined;
|
|
105
|
+
}): Promise<{
|
|
106
|
+
disabled: {
|
|
107
|
+
id: any;
|
|
108
|
+
name: any;
|
|
109
|
+
location: any;
|
|
110
|
+
}[];
|
|
111
|
+
policyPinned: any;
|
|
112
|
+
}>;
|
|
113
|
+
export function openBackgroundWindow(send: any, url: any, timeoutMs: any): Promise<any>;
|
|
114
|
+
export function openUrl(send: any, url: any, remaining: any): Promise<void>;
|
|
115
|
+
export function placeWindow(send: any, targetId: any, bounds: any, timeoutMs?: number): Promise<any>;
|
|
116
|
+
declare function defaultExec(command: any, args: any, { timeoutMs }?: {
|
|
117
|
+
timeoutMs?: number | undefined;
|
|
118
|
+
}): string;
|
|
119
|
+
export {};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export const BRANDED_CHROME_ARGS: string[];
|
|
3
|
+
export const CDP_LOAD_UNPACKED: "cdp-load-unpacked";
|
|
4
|
+
export const HEADFUL: "headful";
|
|
5
|
+
export const HEADLESS: "headless";
|
|
6
|
+
export const LAUNCH_SERVICES: "launch-services";
|
|
7
|
+
export const LOAD_EXTENSION: "load-extension";
|
|
8
|
+
export const SPAWN: "spawn";
|
|
9
|
+
export const TRANSIENT_VERDICT_TTL_MS: number;
|
|
10
|
+
export const UNLAUNCHABLE_MARKER: "BROWSER_UNLAUNCHABLE:";
|
|
11
|
+
export const assertCdpOwnedByProfile: typeof cdp.assertCdpOwnedByProfile;
|
|
12
|
+
export const cdpListenerPids: typeof cdp.cdpListenerPids;
|
|
13
|
+
export const cdpOwner: typeof cdp.cdpOwner;
|
|
14
|
+
export const waitForCdpOwner: typeof cdp.waitForCdpOwner;
|
|
15
|
+
export function brandedChromeCandidates(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, home?: string): string[];
|
|
16
|
+
export function browserMode(env?: NodeJS.ProcessEnv): {
|
|
17
|
+
mode: string;
|
|
18
|
+
path?: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
mode: string;
|
|
21
|
+
path: string;
|
|
22
|
+
};
|
|
23
|
+
export function browserVersion(executable: any): string | null;
|
|
24
|
+
export const connectBrowserCdp: typeof cdp.connectBrowserCdp;
|
|
25
|
+
export function defaultCachePath(env?: NodeJS.ProcessEnv): string;
|
|
26
|
+
export function describeBrowser(executable: any): {
|
|
27
|
+
bin: any;
|
|
28
|
+
browser: string;
|
|
29
|
+
version: string | null;
|
|
30
|
+
extensionLoading: string;
|
|
31
|
+
};
|
|
32
|
+
export function effectiveLaunchMethod(executable: any, launchMethod: any, platform?: NodeJS.Platform): "launch-services" | "spawn";
|
|
33
|
+
export const expectedExtensionId: typeof cdp.expectedExtensionId;
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} extensionDir
|
|
36
|
+
* @param {string} extensionLoading
|
|
37
|
+
* @returns {string[]}
|
|
38
|
+
*/
|
|
39
|
+
export function extensionLaunchArgs(extensionDir: string, extensionLoading: string): string[];
|
|
40
|
+
export function extensionLoadingFor(executable: any): "cdp-load-unpacked" | "load-extension";
|
|
41
|
+
export function isBrandedChrome(executable: any): boolean;
|
|
42
|
+
export const loadUnpackedExtension: typeof cdp.loadUnpackedExtension;
|
|
43
|
+
export const loadUnpackedOverPort: typeof cdp.loadUnpackedOverPort;
|
|
44
|
+
export function playwrightChromiumExecutable(target: any): {
|
|
45
|
+
error: string;
|
|
46
|
+
executable?: undefined;
|
|
47
|
+
} | {
|
|
48
|
+
executable: string;
|
|
49
|
+
error?: undefined;
|
|
50
|
+
};
|
|
51
|
+
export function probeCacheKey(executable: any, version: any, launchMethod?: string, display?: string): string;
|
|
52
|
+
export function probeLaunch(executable: any, { launchMethod, display, settleMs, startupMs, renderAttempts, }?: {
|
|
53
|
+
launchMethod?: string | undefined;
|
|
54
|
+
display?: string | undefined;
|
|
55
|
+
settleMs?: number | undefined;
|
|
56
|
+
startupMs?: number | undefined;
|
|
57
|
+
renderAttempts?: number | undefined;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
ok: any;
|
|
60
|
+
reason: any;
|
|
61
|
+
transient: boolean;
|
|
62
|
+
launchMethod: string;
|
|
63
|
+
display: string;
|
|
64
|
+
durationMs: number;
|
|
65
|
+
}>;
|
|
66
|
+
export function readProbeCache(cachePath: any): any;
|
|
67
|
+
export function renderCheck(port: any): Promise<{
|
|
68
|
+
ok: boolean;
|
|
69
|
+
reason?: undefined;
|
|
70
|
+
} | {
|
|
71
|
+
ok: boolean;
|
|
72
|
+
reason: any;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* @param {{
|
|
76
|
+
* env?: NodeJS.ProcessEnv,
|
|
77
|
+
* cft?: () => { executable?: string, error?: string },
|
|
78
|
+
* probe?: typeof probeLaunch,
|
|
79
|
+
* cachePath?: string,
|
|
80
|
+
* chromeCandidates?: string[],
|
|
81
|
+
* exists?: (file: string) => boolean,
|
|
82
|
+
* describe?: typeof describeBrowser,
|
|
83
|
+
* now?: () => Date,
|
|
84
|
+
* launchMethod?: string,
|
|
85
|
+
* display?: string,
|
|
86
|
+
* recorded?: string | null,
|
|
87
|
+
* managedChrome?: typeof readManagedChromePolicy,
|
|
88
|
+
* }} [options]
|
|
89
|
+
*/
|
|
90
|
+
export function resolveBrowser({ env, cft, probe, cachePath, chromeCandidates, exists, describe, now, launchMethod, display, recorded, managedChrome, }?: {
|
|
91
|
+
env?: NodeJS.ProcessEnv;
|
|
92
|
+
cft?: () => {
|
|
93
|
+
executable?: string;
|
|
94
|
+
error?: string;
|
|
95
|
+
};
|
|
96
|
+
probe?: typeof probeLaunch;
|
|
97
|
+
cachePath?: string;
|
|
98
|
+
chromeCandidates?: string[];
|
|
99
|
+
exists?: (file: string) => boolean;
|
|
100
|
+
describe?: typeof describeBrowser;
|
|
101
|
+
now?: () => Date;
|
|
102
|
+
launchMethod?: string;
|
|
103
|
+
display?: string;
|
|
104
|
+
recorded?: string | null;
|
|
105
|
+
managedChrome?: typeof readManagedChromePolicy;
|
|
106
|
+
}): Promise<{
|
|
107
|
+
source: any;
|
|
108
|
+
resolvedAt: string;
|
|
109
|
+
bin: any;
|
|
110
|
+
browser: string;
|
|
111
|
+
version: string | null;
|
|
112
|
+
extensionLoading: string;
|
|
113
|
+
schemaVersion: number;
|
|
114
|
+
}>;
|
|
115
|
+
export function withProbeLock(cachePath: any, key: any, fn: any, { waitMs, beforeClaim, readStartTime }?: {
|
|
116
|
+
waitMs?: number | undefined;
|
|
117
|
+
beforeClaim?: null | undefined;
|
|
118
|
+
readStartTime?: typeof startTimeOf | undefined;
|
|
119
|
+
}): Promise<any>;
|
|
120
|
+
export function readManagedChromePolicy({ platform, plists, exists, readKey, extensionName, }?: {
|
|
121
|
+
platform?: NodeJS.Platform | undefined;
|
|
122
|
+
plists?: string[] | undefined;
|
|
123
|
+
exists?: ((file: any) => boolean) | undefined;
|
|
124
|
+
readKey?: typeof readPolicyKey | undefined;
|
|
125
|
+
extensionName?: typeof installedExtensionName | undefined;
|
|
126
|
+
}): {
|
|
127
|
+
forcedExtensions: {
|
|
128
|
+
id: any;
|
|
129
|
+
name: any;
|
|
130
|
+
}[];
|
|
131
|
+
signinForced: boolean;
|
|
132
|
+
sources: string[];
|
|
133
|
+
} | null;
|
|
134
|
+
export function managedChromePlists(env?: NodeJS.ProcessEnv): string[];
|
|
135
|
+
export function runCli(argv?: string[]): void;
|
|
136
|
+
import cdp = require("./browser-cdp.cjs");
|
|
137
|
+
declare function startTimeOf(pid: any, timeoutMs: any): string | null;
|
|
138
|
+
declare function readPolicyKey(file: any, key: any): any;
|
|
139
|
+
declare function installedExtensionName(id: any, home?: string): any;
|
|
140
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const DETACHED_LAUNCH_UNPROVEN_FILENAME: ".farmslot-detached-launch-unproven";
|
|
2
|
+
export const RUNTIME_IDENTITY_FILENAME: "extension-runtime-identity.json";
|
|
3
|
+
export const RUNTIME_NONCE_PREFIX: "--farmslot-runtime-nonce=";
|
|
4
|
+
export function automationRuntimeArgs(): string[];
|
|
5
|
+
export function clearDetachedLaunchUnproven(profile: any): void;
|
|
6
|
+
export function clearValidationPortQuarantine(port: any, profile: any, lease: any): void;
|
|
7
|
+
export function createRuntimeIdentityNonce(): string;
|
|
8
|
+
export function detachedLaunchUnprovenPath(profile: any): string;
|
|
9
|
+
export function hasDetachedLaunchUnproven(profile: any): boolean;
|
|
10
|
+
export function isolatedProfileArgs(platform?: NodeJS.Platform): string[];
|
|
11
|
+
export function markDetachedLaunchUnproven(profile: any): string;
|
|
12
|
+
export function markValidationPortLaunchUnproven(port: any, profile: any, lease: any): string;
|
|
13
|
+
export function quarantineDetachedLaunch(profile: any, reason: any): string;
|
|
14
|
+
export function quarantineValidationPort(port: any, profile: any, reason: any): string;
|
|
15
|
+
export function readValidationPortQuarantine(port: any): {
|
|
16
|
+
path: string;
|
|
17
|
+
} | {
|
|
18
|
+
lease?: any;
|
|
19
|
+
path: string;
|
|
20
|
+
profile: any;
|
|
21
|
+
} | null;
|
|
22
|
+
export function remoteDebuggingArgs(cdpPort: any): string[];
|
|
23
|
+
export function removeRuntimeIdentity(runtimeDir: any): void;
|
|
24
|
+
export function runtimeIdentityArgs(nonce: any): string[];
|
|
25
|
+
export function runtimeIdentityPath(runtimeDir: any): string;
|
|
26
|
+
export function shellQuote(value: any): string;
|
|
27
|
+
export function validationLaunchQuarantineError(port: any, ownerProfile: any, requestedProfile: any): Error;
|
|
28
|
+
export function validationPortQuarantinePath(port: any): string;
|
|
29
|
+
export function writeRuntimeIdentity(runtimeDir: any, identity: any): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export const CHROMIUM_EXTENSION_ID_ALPHABET: "abcdefghijklmnop";
|
|
2
|
+
export function extensionIdFromManifestKey(keyBase64: any): string;
|
|
3
|
+
export function extensionIdFromManifestFile(manifestPath: any): string;
|
|
4
|
+
export function extensionIdFromExtensionDir(extensionDir: any): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function activateMacAppByPid(pid: any): boolean;
|
|
2
|
+
export function captureMacFrontmost(): {
|
|
3
|
+
pid: number;
|
|
4
|
+
bundlePath: any;
|
|
5
|
+
name: any;
|
|
6
|
+
} | null;
|
|
7
|
+
export function macBackgroundOpenArgs(application: any, chromeArgs: any): any[];
|
|
8
|
+
export function macFocusDisabled(): boolean;
|
|
9
|
+
export function macFrontmostPid(): number | null;
|
|
10
|
+
export function restoreFrontmostIfOurs(previous: any, ourPids: any): "off" | "kept" | "restored";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function buildEvaluationExpression(callbackOrExpression: any, argument: any): string;
|
|
2
|
+
export function connectBrowserViaCdp(endpoint: any): Promise<any>;
|
|
3
|
+
/**
|
|
4
|
+
* @param {any} page Playwright page
|
|
5
|
+
* @param {string | ((...args: any[]) => unknown)} callbackOrExpression
|
|
6
|
+
* @param {unknown} [argument]
|
|
7
|
+
*/
|
|
8
|
+
export function evaluatePageViaCdp(page: any, callbackOrExpression: string | ((...args: any[]) => unknown), argument?: unknown): Promise<any>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function profileProcessPids(profile: any): number[];
|
|
2
|
+
export function stopProfileProcesses(profile: any, { quietMs, timeoutMs }?: {
|
|
3
|
+
quietMs?: number | undefined;
|
|
4
|
+
timeoutMs?: number | undefined;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} profile
|
|
8
|
+
* @param {{ extraPids?: number[], timeoutMs?: number, waitForAppearanceMs?: number }} [options]
|
|
9
|
+
*/
|
|
10
|
+
export function stopProfileProcessesSync(profile: string, { extraPids, timeoutMs, waitForAppearanceMs }?: {
|
|
11
|
+
extraPids?: number[];
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
waitForAppearanceMs?: number;
|
|
14
|
+
}): void;
|
package/package.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@farmslot/adapter-web",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Web platform adapter for Farmslot recipes: resolve and launch an isolated Chromium, own its CDP port, load unpacked extensions, and keep macOS focus.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./browser-cdp": {
|
|
8
|
+
"types": "./dist/browser-cdp.d.cts",
|
|
9
|
+
"default": "./src/browser-cdp.cjs"
|
|
10
|
+
},
|
|
11
|
+
"./browser-resolver": {
|
|
12
|
+
"types": "./dist/browser-resolver.d.cts",
|
|
13
|
+
"default": "./src/browser-resolver.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./chrome-args": {
|
|
16
|
+
"types": "./dist/chrome-args.d.cts",
|
|
17
|
+
"default": "./src/chrome-args.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./extension-id": {
|
|
20
|
+
"types": "./dist/extension-id.d.cts",
|
|
21
|
+
"default": "./src/extension-id.cjs"
|
|
22
|
+
},
|
|
23
|
+
"./macos-focus": {
|
|
24
|
+
"types": "./dist/macos-focus.d.cts",
|
|
25
|
+
"default": "./src/macos-focus.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./page-target": {
|
|
28
|
+
"types": "./dist/page-target.d.cts",
|
|
29
|
+
"default": "./src/page-target.cjs"
|
|
30
|
+
},
|
|
31
|
+
"./playwright-cdp": {
|
|
32
|
+
"types": "./dist/playwright-cdp.d.cts",
|
|
33
|
+
"default": "./src/playwright-cdp.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./validation-launch-supervisor": {
|
|
36
|
+
"types": "./dist/validation-launch-supervisor.d.cts",
|
|
37
|
+
"default": "./src/validation-launch-supervisor.cjs"
|
|
38
|
+
},
|
|
39
|
+
"./validation-process-ownership": {
|
|
40
|
+
"types": "./dist/validation-process-ownership.d.cts",
|
|
41
|
+
"default": "./src/validation-process-ownership.cjs"
|
|
42
|
+
},
|
|
43
|
+
"./package.json": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"typecheck": "tsc --noEmit --project tsconfig.json && yarn build && tsc --project tsconfig.consumer.json",
|
|
47
|
+
"test": "node --test \"test/*.test.cjs\"",
|
|
48
|
+
"format": "prettier --write --ignore-path ../../.prettierignore .",
|
|
49
|
+
"format:check": "prettier --check --ignore-path ../../.prettierignore .",
|
|
50
|
+
"lint": "eslint \"src/**/*.cjs\" \"test/**/*.cjs\" \"test/**/*.ts\"",
|
|
51
|
+
"lint:fix": "eslint \"src/**/*.cjs\" \"test/**/*.cjs\" \"test/**/*.ts\" --fix",
|
|
52
|
+
"quality": "prettier --check --ignore-path ../../.prettierignore . && eslint \"src/**/*.cjs\" \"test/**/*.cjs\" \"test/**/*.ts\" && yarn typecheck && yarn test",
|
|
53
|
+
"build": "rm -rf dist && tsc --project tsconfig.build.json",
|
|
54
|
+
"prepack": "cd ../.. && node scripts/quality/check-farmslot-package-readiness.mjs --require-changelog --packages @farmslot/adapter-web && yarn workspace @farmslot/adapter-web build",
|
|
55
|
+
"prepublishOnly": "node ../../scripts/quality/check-farmslot-package-readiness.mjs --publish --packages @farmslot/adapter-web"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"ws": "^8.18.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.0.0",
|
|
62
|
+
"eslint": "^10.3.0",
|
|
63
|
+
"prettier": "^3.8.3",
|
|
64
|
+
"typescript": "^5.6.0"
|
|
65
|
+
},
|
|
66
|
+
"repository": {
|
|
67
|
+
"type": "git",
|
|
68
|
+
"url": "git+https://github.com/deeeed/farmslot.git",
|
|
69
|
+
"directory": "packages/adapter-web"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/deeeed/farmslot/issues"
|
|
73
|
+
},
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"homepage": "https://farmslot.io/docs/reference/adapter-web",
|
|
76
|
+
"keywords": [
|
|
77
|
+
"farmslot",
|
|
78
|
+
"recipe",
|
|
79
|
+
"adapter",
|
|
80
|
+
"chrome",
|
|
81
|
+
"cdp",
|
|
82
|
+
"agentic-engineering"
|
|
83
|
+
],
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=22.12.0"
|
|
86
|
+
},
|
|
87
|
+
"files": [
|
|
88
|
+
"README.md",
|
|
89
|
+
"LICENSE",
|
|
90
|
+
"CHANGELOG.md",
|
|
91
|
+
"src/**/*.cjs",
|
|
92
|
+
"dist/**/*.d.cts"
|
|
93
|
+
],
|
|
94
|
+
"publishConfig": {
|
|
95
|
+
"access": "public"
|
|
96
|
+
}
|
|
97
|
+
}
|