trawl-devices-agent 0.1.0 → 0.2.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 CHANGED
@@ -14,8 +14,13 @@ The token also lives in `~/.trawl-devices/agent.json` (mode 0600).
14
14
 
15
15
  Install a browser once: `npx playwright install chromium`.
16
16
 
17
- Flags: `--workspace` (default: cwd), `--port` (8787, next free port if taken),
18
- `--proxy-port` (8080, Trawl's proxy), `--keep-runs` (50).
17
+ Flags: `--workspace` (default: `~/trawl-devices`), `--port` (8787, next free port
18
+ if taken), `--proxy-port` (8080, Trawl's proxy), `--keep-runs` (50),
19
+ `--ensure-browser` (install the Playwright browser first — a no-op once it is
20
+ there), `--browser` (chromium by default).
21
+
22
+ Trawl 1.8.0 and newer starts the agent for you from the Devices tab; running it
23
+ by hand is the fallback.
19
24
 
20
25
  ## Workspace layout
21
26
 
@@ -0,0 +1,48 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import path from "node:path";
5
+ /**
6
+ * Install a Playwright browser if it is missing. Runs Playwright's own CLI from
7
+ * this package's dependency tree, so it works under `npx` with no global
8
+ * install, and streams progress to our stdout — the plugin shows that log.
9
+ *
10
+ * Already-installed browsers make this a no-op that finishes in about a second.
11
+ */
12
+ export async function ensureBrowser(browser) {
13
+ const require = createRequire(import.meta.url);
14
+ let cli;
15
+ try {
16
+ // Playwright's `exports` map hides cli.js, so go through package.json + bin.
17
+ const manifestPath = require.resolve("playwright/package.json");
18
+ const manifest = require("playwright/package.json");
19
+ const relative = manifest.bin?.playwright ?? "cli.js";
20
+ cli = path.join(path.dirname(manifestPath), relative);
21
+ if (!existsSync(cli))
22
+ throw new Error(`not found: ${cli}`);
23
+ }
24
+ catch (err) {
25
+ console.log(`[browser] cannot locate the Playwright CLI (${err.message}); skipping ${browser}`);
26
+ return;
27
+ }
28
+ console.log(`[browser] ensuring ${browser} is installed…`);
29
+ await new Promise((resolve) => {
30
+ const child = spawn(process.execPath, [cli, "install", browser], { stdio: ["ignore", "pipe", "pipe"] });
31
+ const echo = (chunk) => {
32
+ const text = chunk.toString().trimEnd();
33
+ if (text)
34
+ console.log(`[browser] ${text}`);
35
+ };
36
+ child.stdout.on("data", echo);
37
+ child.stderr.on("data", echo);
38
+ child.on("error", (err) => {
39
+ console.log(`[browser] install failed: ${err.message}`);
40
+ resolve();
41
+ });
42
+ child.on("close", (code) => {
43
+ console.log(code === 0 ? `[browser] ${browser} ready` : `[browser] install exited with ${code}`);
44
+ resolve();
45
+ });
46
+ });
47
+ }
48
+ //# sourceMappingURL=browsers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browsers.js","sourceRoot":"","sources":["../src/browsers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA0C;IAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,6EAA6E;QAC7E,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,yBAAyB,CAAqC,CAAC;QACxF,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,UAAU,IAAI,QAAQ,CAAC;QACtD,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,+CAAgD,GAAa,CAAC,OAAO,eAAe,OAAO,EAAE,CAAC,CAAC;QAC3G,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,gBAAgB,CAAC,CAAC;IAC3D,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACxG,MAAM,IAAI,GAAG,CAAC,KAAa,EAAQ,EAAE;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,OAAO,QAAQ,CAAC,CAAC,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;YACjG,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/index.js CHANGED
@@ -3,14 +3,18 @@ import { createServer } from "./server.js";
3
3
  import { loadOrCreateToken } from "./auth.js";
4
4
  import { ensureWorkspace } from "./workspace.js";
5
5
  import { pruneRuns } from "./retention.js";
6
+ import { ensureBrowser } from "./browsers.js";
6
7
  import { AGENT_VERSION, DSL_VERSION } from "./version.js";
7
8
  import { STEP_NAMES } from "./steps.js";
8
9
  import { buildRoutes } from "./routes.js";
10
+ import os from "node:os";
11
+ import path from "node:path";
9
12
  const arg = (name, fallback) => {
10
13
  const hit = process.argv.find((a) => a.startsWith(`--${name}=`));
11
14
  return hit ? hit.slice(name.length + 3) : fallback;
12
15
  };
13
- const workspace = arg("workspace", process.cwd());
16
+ // Default to a stable folder in $HOME: a GUI-spawned agent inherits a useless cwd.
17
+ const workspace = arg("workspace", path.join(os.homedir(), "trawl-devices"));
14
18
  const wanted = Number(arg("port", "8787"));
15
19
  const trawlProxyPort = Number(arg("proxy-port", "8080"));
16
20
  const listen = (server, candidate) => new Promise((resolve, reject) => {
@@ -19,6 +23,9 @@ const listen = (server, candidate) => new Promise((resolve, reject) => {
19
23
  });
20
24
  const token = await loadOrCreateToken();
21
25
  await ensureWorkspace(workspace);
26
+ if (process.argv.includes("--ensure-browser")) {
27
+ await ensureBrowser(arg("browser", "chromium"));
28
+ }
22
29
  const pruned = await pruneRuns(workspace, Number(arg("keep-runs", "50")));
23
30
  if (pruned.length)
24
31
  console.log(`pruned ${pruned.length} old run(s)`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Package version, reported by /health. */
2
- export const AGENT_VERSION = "0.1.0";
2
+ export const AGENT_VERSION = "0.2.0";
3
3
  /** Bumped whenever STEP_NAMES changes, so the plugin can demand an update. */
4
4
  export const DSL_VERSION = 1;
5
5
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trawl-devices-agent",
3
- "version": "0.1.0",
4
- "description": "Local sidecar for the Trawl devices plugin records and replays browser scenarios with Playwright.",
3
+ "version": "0.2.0",
4
+ "description": "Local sidecar for the Trawl devices plugin \u2014 records and replays browser scenarios with Playwright.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "trawl-devices-agent": "dist/index.js"