textweb 0.2.3 → 0.2.4

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/mcp/index.js CHANGED
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  const { AgentBrowser } = require('../src/browser');
14
+ const { ensureBrowser } = require('../src/ensure-browser');
14
15
 
15
16
  const SERVER_INFO = {
16
17
  name: 'textweb',
@@ -462,4 +463,7 @@ function main() {
462
463
  });
463
464
  }
464
465
 
465
- main();
466
+ ensureBrowser().then(main).catch((err) => {
467
+ process.stderr.write(`Fatal: ${err.message}\n`);
468
+ process.exit(1);
469
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textweb",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A text-grid web renderer for AI agents — see the web without screenshots",
5
5
  "main": "src/browser.js",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  const { AgentBrowser } = require('./browser');
8
8
  const { createServer } = require('./server');
9
+ const { ensureBrowser } = require('./ensure-browser');
9
10
  const readline = require('readline');
10
11
 
11
12
  // Parse command line arguments
@@ -392,7 +393,9 @@ async function main() {
392
393
  showHelp();
393
394
  return;
394
395
  }
395
-
396
+
397
+ await ensureBrowser();
398
+
396
399
  if (options.serve) {
397
400
  await serve(options);
398
401
  } else if (options.interactive) {
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * ensure-browser.js
5
+ *
6
+ * Checks whether Playwright's Chromium is installed and, when running
7
+ * in an interactive terminal, offers to install it automatically.
8
+ *
9
+ * All output goes to stderr so it never pollutes stdout-based protocols
10
+ * (e.g. the MCP JSON-RPC transport).
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const { spawnSync } = require('child_process');
15
+ const readline = require('readline');
16
+
17
+ function ask(prompt) {
18
+ return new Promise((resolve) => {
19
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
20
+ rl.question(prompt, (answer) => {
21
+ rl.close();
22
+ resolve(answer.trim());
23
+ });
24
+ });
25
+ }
26
+
27
+ function log(msg) {
28
+ process.stderr.write(msg + '\n');
29
+ }
30
+
31
+ function isInstalled() {
32
+ try {
33
+ const { chromium } = require('playwright');
34
+ const execPath = chromium.executablePath();
35
+ return fs.existsSync(execPath);
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+
41
+ function install() {
42
+ // Prefer the local playwright CLI (bundled with the dep) over npx
43
+ let cliPath = null;
44
+ try {
45
+ cliPath = require.resolve('playwright/cli.js');
46
+ } catch { /* fall through to npx */ }
47
+
48
+ const result = cliPath
49
+ ? spawnSync(process.execPath, [cliPath, 'install', 'chromium'], { stdio: 'inherit' })
50
+ : spawnSync('npx', ['playwright', 'install', 'chromium'], { stdio: 'inherit', shell: true });
51
+
52
+ return result.status === 0;
53
+ }
54
+
55
+ async function ensureBrowser() {
56
+ if (isInstalled()) return;
57
+
58
+ log('');
59
+ log('⚠ Playwright Chromium is not installed — textweb needs it to browse the web.');
60
+
61
+ if (process.stdin.isTTY) {
62
+ const answer = await ask(' Install it now? (Y/n) ');
63
+ if (answer.toLowerCase() === 'n') {
64
+ log('');
65
+ log(' Run manually: npx playwright install chromium');
66
+ log('');
67
+ process.exit(1);
68
+ }
69
+ } else {
70
+ log('');
71
+ log(' Run: npx playwright install chromium');
72
+ log('');
73
+ process.exit(1);
74
+ }
75
+
76
+ log('');
77
+ log(' Installing Chromium — this takes ~30 seconds the first time…');
78
+ log('');
79
+
80
+ if (!install()) {
81
+ log('');
82
+ log(' Installation failed. Run manually: npx playwright install chromium');
83
+ log('');
84
+ process.exit(1);
85
+ }
86
+
87
+ log('');
88
+ log('✓ Chromium installed successfully!');
89
+ log('');
90
+ }
91
+
92
+ module.exports = { ensureBrowser };