@anweat/dsh-browser 0.1.12 → 0.1.13-alpha.1
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/LICENSE +21 -21
- package/README.md +382 -371
- package/cordis.patch.yml +26 -26
- package/lib/automation-assets-rpc.js +47 -6
- package/lib/automation-assets-rpc.js.map +1 -1
- package/lib/browser-service.js +57 -57
- package/lib/client/automation-assets-client.d.ts +1 -1
- package/lib/client/automation-assets-client.js +1 -1
- package/lib/client/automation-assets-client.js.map +1 -1
- package/lib/client/context-types.d.ts +1 -1
- package/lib/client/form.d.ts +2 -1
- package/lib/client/form.js.map +1 -1
- package/lib/client/styles.js +12 -12
- package/lib/client.js +1 -1
- package/lib/client.js.map +1 -1
- package/lib/scripts.js +27 -27
- package/package.json +150 -133
- package/scripts/check-client-bundle.mjs +15 -15
- package/scripts/clean-lib.mjs +3 -3
- package/scripts/install-browser.mjs +18 -18
package/lib/scripts.js
CHANGED
|
@@ -4,57 +4,57 @@
|
|
|
4
4
|
* @module dsh-browser/scripts
|
|
5
5
|
*/
|
|
6
6
|
import crypto from 'node:crypto';
|
|
7
|
-
const header = (name, description) => `// ==UserScript==
|
|
8
|
-
// @name ${name}
|
|
9
|
-
// @description ${description}
|
|
10
|
-
// @match *://*/*
|
|
11
|
-
// @grant none
|
|
7
|
+
const header = (name, description) => `// ==UserScript==
|
|
8
|
+
// @name ${name}
|
|
9
|
+
// @description ${description}
|
|
10
|
+
// @match *://*/*
|
|
11
|
+
// @grant none
|
|
12
12
|
// ==/UserScript==`;
|
|
13
13
|
export const BUILTIN_SCRIPTS = [
|
|
14
14
|
{
|
|
15
15
|
id: 'article-clean',
|
|
16
16
|
name: 'Article Clean Reader',
|
|
17
17
|
description: 'Extract title, canonical URL, headings, and readable article text.',
|
|
18
|
-
source: `${header('Article Clean Reader', 'Extract readable article content without mutating the page.')}
|
|
19
|
-
const root = document.querySelector('article, main, [role="main"]') || document.body
|
|
20
|
-
return {
|
|
21
|
-
title: document.title,
|
|
22
|
-
canonicalUrl: document.querySelector('link[rel="canonical"]')?.href || location.href,
|
|
23
|
-
headings: [...root.querySelectorAll('h1,h2,h3')].slice(0, 100).map(el => (el.textContent || '').trim()).filter(Boolean),
|
|
24
|
-
text: (root.innerText || root.textContent || '').trim().slice(0, 50000),
|
|
18
|
+
source: `${header('Article Clean Reader', 'Extract readable article content without mutating the page.')}
|
|
19
|
+
const root = document.querySelector('article, main, [role="main"]') || document.body
|
|
20
|
+
return {
|
|
21
|
+
title: document.title,
|
|
22
|
+
canonicalUrl: document.querySelector('link[rel="canonical"]')?.href || location.href,
|
|
23
|
+
headings: [...root.querySelectorAll('h1,h2,h3')].slice(0, 100).map(el => (el.textContent || '').trim()).filter(Boolean),
|
|
24
|
+
text: (root.innerText || root.textContent || '').trim().slice(0, 50000),
|
|
25
25
|
}`,
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
id: 'links',
|
|
29
29
|
name: 'Link Inventory',
|
|
30
30
|
description: 'Extract up to 200 visible links with absolute URLs.',
|
|
31
|
-
source: `${header('Link Inventory', 'Extract visible links without clicking them.')}
|
|
32
|
-
return [...document.querySelectorAll('a[href]')].slice(0, 200).map(a => ({
|
|
33
|
-
text: (a.textContent || '').trim().slice(0, 500),
|
|
34
|
-
url: a.href,
|
|
31
|
+
source: `${header('Link Inventory', 'Extract visible links without clicking them.')}
|
|
32
|
+
return [...document.querySelectorAll('a[href]')].slice(0, 200).map(a => ({
|
|
33
|
+
text: (a.textContent || '').trim().slice(0, 500),
|
|
34
|
+
url: a.href,
|
|
35
35
|
})).filter(item => item.url)`,
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
id: 'jsonld',
|
|
39
39
|
name: 'JSON-LD Extractor',
|
|
40
40
|
description: 'Read structured JSON-LD blocks from the page.',
|
|
41
|
-
source: `${header('JSON-LD Extractor', 'Extract JSON-LD structured data.')}
|
|
42
|
-
return [...document.querySelectorAll('script[type="application/ld+json"]')].slice(0, 20).map(node => {
|
|
43
|
-
try { return JSON.parse(node.textContent || 'null') } catch { return { invalid: true, text: (node.textContent || '').slice(0, 2000) } }
|
|
41
|
+
source: `${header('JSON-LD Extractor', 'Extract JSON-LD structured data.')}
|
|
42
|
+
return [...document.querySelectorAll('script[type="application/ld+json"]')].slice(0, 20).map(node => {
|
|
43
|
+
try { return JSON.parse(node.textContent || 'null') } catch { return { invalid: true, text: (node.textContent || '').slice(0, 2000) } }
|
|
44
44
|
})`,
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
id: 'forms',
|
|
48
48
|
name: 'Form Structure',
|
|
49
49
|
description: 'Describe forms and controls without returning current values.',
|
|
50
|
-
source: `${header('Form Structure', 'Describe form controls without exposing entered values.')}
|
|
51
|
-
return [...document.forms].slice(0, 30).map((form, formIndex) => ({
|
|
52
|
-
form: formIndex,
|
|
53
|
-
action: form.action,
|
|
54
|
-
method: form.method,
|
|
55
|
-
controls: [...form.elements].slice(0, 100).map(el => ({
|
|
56
|
-
tag: el.tagName.toLowerCase(), type: el.type || '', name: el.name || '', id: el.id || '', required: !!el.required,
|
|
57
|
-
})),
|
|
50
|
+
source: `${header('Form Structure', 'Describe form controls without exposing entered values.')}
|
|
51
|
+
return [...document.forms].slice(0, 30).map((form, formIndex) => ({
|
|
52
|
+
form: formIndex,
|
|
53
|
+
action: form.action,
|
|
54
|
+
method: form.method,
|
|
55
|
+
controls: [...form.elements].slice(0, 100).map(el => ({
|
|
56
|
+
tag: el.tagName.toLowerCase(), type: el.type || '', name: el.name || '', id: el.id || '', required: !!el.required,
|
|
57
|
+
})),
|
|
58
58
|
}))`,
|
|
59
59
|
},
|
|
60
60
|
];
|
package/package.json
CHANGED
|
@@ -1,133 +1,150 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@anweat/dsh-browser",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Self-contained browser runtime plugin for DeepSeek Harness (scoped @anweat) — bundles Playwright (chromium) and OpenCLI as plugin-local dependencies (with global-reuse fallback), exposes a `browser` service and interactive browser tools.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "lib/index.js",
|
|
8
|
-
"types": "lib/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./lib/index.d.ts",
|
|
12
|
-
"default": "./lib/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./client": {
|
|
15
|
-
"types": "./lib/client/index.d.ts",
|
|
16
|
-
"default": "./lib/client.js"
|
|
17
|
-
},
|
|
18
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
19
|
-
"./package.json": "./package.json"
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"lib",
|
|
23
|
-
"cordis.patch.yml",
|
|
24
|
-
"README.md",
|
|
25
|
-
"scripts",
|
|
26
|
-
"LICENSE"
|
|
27
|
-
],
|
|
28
|
-
"engines": {
|
|
29
|
-
"node": "^22.19 || >=24"
|
|
30
|
-
},
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"@deepseek-ai/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"@deepseek-ai/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"@deepseek-ai/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
"@deepseek-ai/
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"@
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"@
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@anweat/dsh-browser",
|
|
3
|
+
"version": "0.1.13-alpha.1",
|
|
4
|
+
"description": "Self-contained browser runtime plugin for DeepSeek Harness (scoped @anweat) — bundles Playwright (chromium) and OpenCLI as plugin-local dependencies (with global-reuse fallback), exposes a `browser` service and interactive browser tools.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"default": "./lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./client": {
|
|
15
|
+
"types": "./lib/client/index.d.ts",
|
|
16
|
+
"default": "./lib/client.js"
|
|
17
|
+
},
|
|
18
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"lib",
|
|
23
|
+
"cordis.patch.yml",
|
|
24
|
+
"README.md",
|
|
25
|
+
"scripts",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": "^22.19 || >=24"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "node scripts/clean-lib.mjs && tsc -p tsconfig.json && tsdown",
|
|
33
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
34
|
+
"test": "node --test --experimental-transform-types test/*.test.ts",
|
|
35
|
+
"test:client-bundle": "node scripts/check-client-bundle.mjs",
|
|
36
|
+
"verify": "pnpm run typecheck && pnpm run build && pnpm test && pnpm run test:client-bundle",
|
|
37
|
+
"prepublishOnly": "pnpm run verify",
|
|
38
|
+
"prepare": "npm run build"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
42
|
+
"@deepseek-ai/dsh-tools": "0.1.5-alpha.1",
|
|
43
|
+
"@deepseek-ai/dsh-client-connection": "0.1.5-alpha.1",
|
|
44
|
+
"@deepseek-ai/dsh-client-locale": "0.1.5-alpha.1",
|
|
45
|
+
"@deepseek-ai/dsh-client-store": "0.1.5-alpha.1",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.5-alpha.1",
|
|
47
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.5-alpha.1",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-alpha.1",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-alpha.1",
|
|
50
|
+
"@deepseek-ai/dsh-settings": "0.1.5-alpha.1",
|
|
51
|
+
"@deepseek-ai/schemastery": "3.18.2"
|
|
52
|
+
},
|
|
53
|
+
"peerDependenciesMeta": {
|
|
54
|
+
"@deepseek-ai/cordis": {
|
|
55
|
+
"optional": true
|
|
56
|
+
},
|
|
57
|
+
"@deepseek-ai/dsh-tools": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"@deepseek-ai/dsh-client-connection": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"@deepseek-ai/dsh-client-store": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-renderer": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-settings": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@deepseek-ai/dsh-settings": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@deepseek-ai/schemastery": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"dependencies": {
|
|
89
|
+
"@jackwener/opencli": "^1.8.6",
|
|
90
|
+
"patchright": "^1.62.1",
|
|
91
|
+
"playwright": "^1.60.0"
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
95
|
+
"@deepseek-ai/dsh-agent": "0.1.5-alpha.1",
|
|
96
|
+
"@deepseek-ai/dsh-code-runtime": "0.1.5-alpha.1",
|
|
97
|
+
"@deepseek-ai/dsh-invariants": "0.1.5-alpha.1",
|
|
98
|
+
"@deepseek-ai/dsh-llm": "0.1.5-alpha.1",
|
|
99
|
+
"@deepseek-ai/dsh-scope": "0.1.5-alpha.1",
|
|
100
|
+
"@deepseek-ai/dsh-session": "0.1.5-alpha.1",
|
|
101
|
+
"@deepseek-ai/dsh-session-projection": "0.1.5-alpha.1",
|
|
102
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.5-alpha.1",
|
|
103
|
+
"@deepseek-ai/dsh-user-approval": "0.1.5-alpha.1",
|
|
104
|
+
"@deepseek-ai/dsh-tools": "0.1.5-alpha.1",
|
|
105
|
+
"@deepseek-ai/dsh-client-connection": "0.1.5-alpha.1",
|
|
106
|
+
"@deepseek-ai/dsh-client-locale": "0.1.5-alpha.1",
|
|
107
|
+
"@deepseek-ai/dsh-client-store": "0.1.5-alpha.1",
|
|
108
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.5-alpha.1",
|
|
109
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.5-alpha.1",
|
|
110
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-alpha.1",
|
|
111
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-alpha.1",
|
|
112
|
+
"@deepseek-ai/dsh-settings": "0.1.5-alpha.1",
|
|
113
|
+
"@deepseek-ai/schemastery": "3.18.2",
|
|
114
|
+
"@types/react": "~18.3.1",
|
|
115
|
+
"@types/react-dom": "~18.3.1",
|
|
116
|
+
"react": "^18.2.0",
|
|
117
|
+
"react-dom": "18.2.0",
|
|
118
|
+
"tsdown": "^0.22.2",
|
|
119
|
+
"typescript": "^5.6.0",
|
|
120
|
+
"@types/node": "^22.0.0"
|
|
121
|
+
},
|
|
122
|
+
"dsh": {
|
|
123
|
+
"client": {
|
|
124
|
+
"inject": [
|
|
125
|
+
"@deepseek-ai/dsh-client-connection",
|
|
126
|
+
"@deepseek-ai/dsh-client-locale",
|
|
127
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
128
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
129
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins"
|
|
130
|
+
],
|
|
131
|
+
"platform": "web"
|
|
132
|
+
},
|
|
133
|
+
"bundle": {
|
|
134
|
+
"patch": "./cordis.patch.yml"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"packageManager": "pnpm@11.7.0",
|
|
138
|
+
"repository": {
|
|
139
|
+
"type": "git",
|
|
140
|
+
"url": "git+https://github.com/anweat/dsh-browser.git"
|
|
141
|
+
},
|
|
142
|
+
"keywords": [
|
|
143
|
+
"dsh",
|
|
144
|
+
"deepseek-harness",
|
|
145
|
+
"plugin",
|
|
146
|
+
"browser",
|
|
147
|
+
"playwright",
|
|
148
|
+
"opencli"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import assert from 'node:assert/strict'
|
|
2
|
-
import { readFile } from 'node:fs/promises'
|
|
3
|
-
|
|
4
|
-
const source = await readFile(new URL('../lib/client.js', import.meta.url), 'utf8')
|
|
5
|
-
const sourceMap = JSON.parse(await readFile(new URL('../lib/client.js.map', import.meta.url), 'utf8'))
|
|
6
|
-
const imports = [...source.matchAll(/\brequire\((['"])([^'"]+)\1\)/g)].map(match => match[2])
|
|
7
|
-
const allowed = new Set(['react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', '@deepseek-ai/cordis', '@deepseek-ai/dsh-client-
|
|
8
|
-
const forbidden = [...new Set(imports.filter(id => !allowed.has(id)))].sort()
|
|
9
|
-
|
|
10
|
-
assert.deepEqual(forbidden, [], `client bundle contains unavailable imports: ${forbidden.join(', ')}`)
|
|
11
|
-
assert.match(source, /settings\.plugin\.item/)
|
|
12
|
-
assert.match(source, /dsh-browser/)
|
|
13
|
-
assert.match(source, /Browser automation/)
|
|
14
|
-
assert.equal('sourcesContent' in sourceMap, false, 'client source map must exclude source contents')
|
|
15
|
-
console.log(`client bundle check passed (${[...new Set(imports)].length} module-table imports)`)
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
3
|
+
|
|
4
|
+
const source = await readFile(new URL('../lib/client.js', import.meta.url), 'utf8')
|
|
5
|
+
const sourceMap = JSON.parse(await readFile(new URL('../lib/client.js.map', import.meta.url), 'utf8'))
|
|
6
|
+
const imports = [...source.matchAll(/\brequire\((['"])([^'"]+)\1\)/g)].map(match => match[2])
|
|
7
|
+
const allowed = new Set(['react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', '@deepseek-ai/cordis', '@deepseek-ai/dsh-client-store', '@deepseek-ai/dsh-client-ui-slots'])
|
|
8
|
+
const forbidden = [...new Set(imports.filter(id => !allowed.has(id)))].sort()
|
|
9
|
+
|
|
10
|
+
assert.deepEqual(forbidden, [], `client bundle contains unavailable imports: ${forbidden.join(', ')}`)
|
|
11
|
+
assert.match(source, /settings\.plugin\.item/)
|
|
12
|
+
assert.match(source, /dsh-browser/)
|
|
13
|
+
assert.match(source, /Browser automation/)
|
|
14
|
+
assert.equal('sourcesContent' in sourceMap, false, 'client source map must exclude source contents')
|
|
15
|
+
console.log(`client bundle check passed (${[...new Set(imports)].length} module-table imports)`)
|
package/scripts/clean-lib.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { rm } from 'node:fs/promises'
|
|
2
|
-
|
|
3
|
-
await rm(new URL('../lib', import.meta.url), { recursive: true, force: true })
|
|
1
|
+
import { rm } from 'node:fs/promises'
|
|
2
|
+
|
|
3
|
+
await rm(new URL('../lib', import.meta.url), { recursive: true, force: true })
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Installs the Playwright browser(s) used by the dsh-browser plugin, using the
|
|
3
|
-
// playwright CLI from THIS plugin's node_modules (not the global install).
|
|
4
|
-
// Usage: node scripts/install-browser.mjs [chromium|msedge|...] (default chromium)
|
|
5
|
-
import { createRequire } from 'node:module'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
|
-
import { spawnSync } from 'node:child_process'
|
|
8
|
-
import path from 'node:path'
|
|
9
|
-
|
|
10
|
-
const root = fileURLToPath(new URL('..', import.meta.url))
|
|
11
|
-
const req = createRequire(path.join(root, 'package.json'))
|
|
12
|
-
const cli = path.join(path.dirname(req.resolve('playwright/package.json')), 'cli.js')
|
|
13
|
-
|
|
14
|
-
const channels = process.argv.slice(2)
|
|
15
|
-
const targets = channels.length ? channels : ['chromium']
|
|
16
|
-
console.log('[dsh-browser] installing playwright browsers:', targets.join(', '))
|
|
17
|
-
const r = spawnSync(process.execPath, [cli, 'install', ...targets], { stdio: 'inherit', cwd: root })
|
|
18
|
-
process.exit(r.status ?? 1)
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Installs the Playwright browser(s) used by the dsh-browser plugin, using the
|
|
3
|
+
// playwright CLI from THIS plugin's node_modules (not the global install).
|
|
4
|
+
// Usage: node scripts/install-browser.mjs [chromium|msedge|...] (default chromium)
|
|
5
|
+
import { createRequire } from 'node:module'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
import { spawnSync } from 'node:child_process'
|
|
8
|
+
import path from 'node:path'
|
|
9
|
+
|
|
10
|
+
const root = fileURLToPath(new URL('..', import.meta.url))
|
|
11
|
+
const req = createRequire(path.join(root, 'package.json'))
|
|
12
|
+
const cli = path.join(path.dirname(req.resolve('playwright/package.json')), 'cli.js')
|
|
13
|
+
|
|
14
|
+
const channels = process.argv.slice(2)
|
|
15
|
+
const targets = channels.length ? channels : ['chromium']
|
|
16
|
+
console.log('[dsh-browser] installing playwright browsers:', targets.join(', '))
|
|
17
|
+
const r = spawnSync(process.execPath, [cli, 'install', ...targets], { stdio: 'inherit', cwd: root })
|
|
18
|
+
process.exit(r.status ?? 1)
|