web-extension 0.0.0-stage → 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/AI.md +270 -0
- package/DEVELOPER.md +122 -0
- package/LICENSE +21 -0
- package/README.md +140 -2
- package/dist/index.js +2125 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -4
- package/templates/base/_gitignore +6 -0
- package/templates/base/public/icons/128.png +0 -0
- package/templates/base/public/icons/16.png +0 -0
- package/templates/base/public/icons/48.png +0 -0
- package/templates/features/background/js/src/background/index.js +6 -0
- package/templates/features/background/ts/src/background/index.ts +6 -0
- package/templates/features/content/content-only/js/src/content/index.js +32 -0
- package/templates/features/content/content-only/ts/src/content/index.ts +32 -0
- package/templates/features/content/full/js/src/content/index.js +6 -0
- package/templates/features/content/full/ts/src/content/index.ts +6 -0
- package/templates/features/content/style.css +16 -0
- package/templates/features/devtools/js/src/devtools/devtools.html +9 -0
- package/templates/features/devtools/js/src/devtools/devtools.js +11 -0
- package/templates/features/devtools/js/src/devtools/panel.html +18 -0
- package/templates/features/devtools/ts/src/devtools/devtools.html +9 -0
- package/templates/features/devtools/ts/src/devtools/devtools.ts +11 -0
- package/templates/features/devtools/ts/src/devtools/panel.html +18 -0
- package/templates/features/dnr/rules.json +18 -0
- package/templates/features/extras/storage/js/src/lib/storage.js +31 -0
- package/templates/features/extras/storage/ts/src/lib/storage.ts +15 -0
- package/templates/features/newtab/js/src/newtab/index.html +17 -0
- package/templates/features/newtab/js/src/newtab/main.js +8 -0
- package/templates/features/newtab/js/src/newtab/style.css +30 -0
- package/templates/features/newtab/ts/src/newtab/index.html +17 -0
- package/templates/features/newtab/ts/src/newtab/main.ts +8 -0
- package/templates/features/newtab/ts/src/newtab/style.css +30 -0
- package/templates/features/options/js/src/options/index.html +21 -0
- package/templates/features/options/js/src/options/main.js +11 -0
- package/templates/features/options/js/src/options/style.css +37 -0
- package/templates/features/options/ts/src/options/index.html +21 -0
- package/templates/features/options/ts/src/options/main.ts +11 -0
- package/templates/features/options/ts/src/options/style.css +37 -0
- package/templates/features/popup/js/src/popup/index.html +18 -0
- package/templates/features/popup/js/src/popup/main.js +9 -0
- package/templates/features/popup/js/src/popup/style.css +39 -0
- package/templates/features/popup/ts/src/popup/index.html +18 -0
- package/templates/features/popup/ts/src/popup/main.ts +9 -0
- package/templates/features/popup/ts/src/popup/style.css +39 -0
- package/templates/features/sidepanel/js/src/sidepanel/index.html +17 -0
- package/templates/features/sidepanel/js/src/sidepanel/main.js +7 -0
- package/templates/features/sidepanel/js/src/sidepanel/style.css +25 -0
- package/templates/features/sidepanel/ts/src/sidepanel/index.html +17 -0
- package/templates/features/sidepanel/ts/src/sidepanel/main.ts +7 -0
- package/templates/features/sidepanel/ts/src/sidepanel/style.css +25 -0
- package/templates/js/src/lib/browser.js +9 -0
- package/templates/ts/src/lib/browser.ts +9 -0
package/AI.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# web-extension: AI & Agent System Specification
|
|
2
|
+
|
|
3
|
+
This document provides a deterministic, complete, and unambiguous specification of the `web-extension` CLI. It is structured specifically for AI models, automated agents, and code generators to reason about and execute without guesswork.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. System Overview & Invariants
|
|
8
|
+
|
|
9
|
+
- **Package Name:** `web-extension`
|
|
10
|
+
- **Binary Name:** `web-extension`
|
|
11
|
+
- **Runtime Target:** Node.js >= 20, Bun >= 1.0.0
|
|
12
|
+
- **CLI Architecture:** TypeScript source compiled via `tsup` to a single ESM bundle at `dist/index.js` with shebang `#!/usr/bin/env node`.
|
|
13
|
+
- **Primary Subcommand:** `init`
|
|
14
|
+
- **Default Subcommand Alias:** When invoked without a subcommand (or when the first argument is not recognized as a registered subcommand), the CLI implicitly routes to `init`. For example, `web-extension my-app --lang ts` is identical to `web-extension init my-app --lang ts`.
|
|
15
|
+
- **Top-Level Flags:** `--help` / `-h` and `--version` / `-v` are processed immediately and do not enter the `init` pipeline.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. CLI Execution Modes & Contracts
|
|
20
|
+
|
|
21
|
+
### 2.1 Non-TTY (Scripted / CI) Contract
|
|
22
|
+
- If stdin or stdout is not a TTY (`!process.stdin.isTTY || !process.stdout.isTTY`), interactive prompts cannot be shown.
|
|
23
|
+
- Every required decision that lacks an explicit CLI flag or `--yes` default causes an immediate error with exit code `1`.
|
|
24
|
+
- When `--yes` (or `-y`) is provided, all omitted options fall back to their documented default values.
|
|
25
|
+
|
|
26
|
+
### 2.2 Interactive Contract
|
|
27
|
+
- Uses `@clack/prompts`.
|
|
28
|
+
- Any user cancellation (`Ctrl+C` or escape) invokes `p.cancel('Cancelled.')` and immediately terminates process with exit code `0`.
|
|
29
|
+
- If an option was supplied via CLI flag, its corresponding interactive prompt is skipped.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Flag Parsing & Parameter Matrix
|
|
34
|
+
|
|
35
|
+
All flags can be provided in kebab-case.
|
|
36
|
+
|
|
37
|
+
| Flag | Type | Allowed Values | Default Value (`--yes`) | Notes |
|
|
38
|
+
|---|---|---|---|---|
|
|
39
|
+
| `[dir]` | string (positional) | Any valid path or slug | `my-extension` | First positional argument after subcommand. |
|
|
40
|
+
| `--name` | string | Valid npm package name | Basename of `[dir]` or `my-extension` | Must be lowercase, no spaces, valid regex. |
|
|
41
|
+
| `--if-exists` | string | `cancel`, `overwrite`, `merge` | `cancel` | Action when target directory is not empty. |
|
|
42
|
+
| `--overwrite` | boolean | `true`, `false` | `false` | Convenience alias for `--if-exists overwrite`. |
|
|
43
|
+
| `--lang` | string | `ts`, `js` | `ts` | TypeScript or JavaScript. |
|
|
44
|
+
| `--type` | string | `full`, `content-only` | `full` | Full extension or headless content-script only. |
|
|
45
|
+
| `--browser` | string (repeatable/comma) | `chrome`, `firefox`, `safari` | `chrome` | Target browsers. `chromium` maps to `chrome`. |
|
|
46
|
+
| `--firefox-mv` | number / string | `2`, `3` | `3` | Firefox manifest version. |
|
|
47
|
+
| `--safari-mv` | number / string | `2`, `3` | `3` | Safari manifest version. |
|
|
48
|
+
| `--features` | string (comma) | `background`, `content`, `popup`, `options`, `sidepanel`, `dnr`, `devtools`, `newtab`, `none` | `background,content` | Available only in `full` mode. |
|
|
49
|
+
| `--matches` | string (comma) | WebExtension match patterns | `https://*/*` | Required pattern(s) when `content` is enabled. |
|
|
50
|
+
| `--run-at` | string | `document_start`, `document_end`, `document_idle` | `document_idle` | Content script execution timing. |
|
|
51
|
+
| `--world` | string | `ISOLATED`, `MAIN` | `ISOLATED` | MV3 only. Not permitted with MV2 targets. |
|
|
52
|
+
| `--css` / `--no-css` | boolean | `true`, `false` | `true` | Generate CSS stylesheet for content script. |
|
|
53
|
+
| `--extras` | string (comma) | `contextmenu`, `commands`, `omnibox`, `storage`, `none` | `none` | Additional helpers and boilerplate. |
|
|
54
|
+
| `--pm` | string | `npm`, `pnpm`, `yarn`, `bun` | Auto-detected | Force package manager selection. |
|
|
55
|
+
| `--install` / `--no-install` | boolean | `true`, `false` | `true` | Whether to automatically install dependencies. |
|
|
56
|
+
| `--git` / `--no-git` | boolean | `true`, `false` | `true` | Initialize a Git repository. |
|
|
57
|
+
| `--yes`, `-y` | boolean | `true`, `false` | `false` | Bypass prompts using default values. |
|
|
58
|
+
| `--help`, `-h` | boolean | `true`, `false` | `false` | Display help output and exit `0`. |
|
|
59
|
+
| `--version`, `-v` | boolean | `true`, `false` | `false` | Display package version and exit `0`. |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 4. Validation Rules & Exit Behavior
|
|
64
|
+
|
|
65
|
+
The CLI enforces strict validation with exit code `1` upon invalid inputs or incompatible combinations:
|
|
66
|
+
|
|
67
|
+
### 4.1 Fatal Errors (Exit Code 1)
|
|
68
|
+
1. **Unrecognized Flag Value:** Any value outside the allowed set (e.g. `--browser edge` or `--lang ruby`) aborts with an error listing accepted values.
|
|
69
|
+
2. **Content-Only with Features/Extras:** Supplying `--type content-only` with `--features` or `--extras` is invalid. Content-only extensions contain only content scripts.
|
|
70
|
+
3. **Safari-Only Side Panel:** Specifying `--features sidepanel` when `--browser safari` is the only target is fatal because Safari does not support side panels.
|
|
71
|
+
4. **DNR with Manifest V2:** Specifying `--features dnr` while any target is MV2 is fatal.
|
|
72
|
+
5. **Extras without Background:** Specifying `--extras contextmenu`, `commands`, or `omnibox` without `background` in `--features` is fatal.
|
|
73
|
+
6. **Main World with Manifest V2:** Specifying `--world MAIN` while any target is MV2 is fatal.
|
|
74
|
+
7. **Directory Conflict:** Target directory exists and contains files, but `--if-exists` is `cancel` or unhandled.
|
|
75
|
+
8. **Invalid Package Name:** Package name does not conform to npm package naming rules (`/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/`).
|
|
76
|
+
9. **Invalid Match Pattern:** Pattern does not start with `http://`, `https://`, `*://`, `file://`, or `<all_urls>`.
|
|
77
|
+
|
|
78
|
+
### 4.2 Non-Fatal Warnings
|
|
79
|
+
The CLI prints warnings to stderr but continues execution when:
|
|
80
|
+
- `--firefox-mv` is passed without `firefox` in `--browser`.
|
|
81
|
+
- `--safari-mv` is passed without `safari` in `--browser`.
|
|
82
|
+
- Content script flags (`--matches`, `--run-at`, `--world`, `--css`) are passed when `content` feature is absent.
|
|
83
|
+
- `--git` is requested but the target directory is already inside an existing Git repository.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 5. Browser Capabilities & Target Resolution
|
|
88
|
+
|
|
89
|
+
For each selected browser, the generator maps targets:
|
|
90
|
+
- `chrome` -> `chrome-mv3` (outDir: `dist/chrome-mv3`)
|
|
91
|
+
- `firefox` (MV3) -> `firefox-mv3` (outDir: `dist/firefox-mv3`)
|
|
92
|
+
- `firefox` (MV2) -> `firefox-mv2` (outDir: `dist/firefox-mv2`)
|
|
93
|
+
- `safari` (MV3) -> `safari-mv3` (outDir: `dist/safari-mv3`)
|
|
94
|
+
- `safari` (MV2) -> `safari-mv2` (outDir: `dist/safari-mv2`)
|
|
95
|
+
|
|
96
|
+
### 5.1 Capability Matrix
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
Target MV Worker Scripts Popup SidePanel DNR WorldMain
|
|
100
|
+
------------------------------------------------------------------------------------
|
|
101
|
+
chrome-mv3 3 Yes No action side_panel Yes Yes
|
|
102
|
+
firefox-mv3 3 No Yes action sidebar_action Yes Yes
|
|
103
|
+
firefox-mv2 2 No Yes browser_action sidebar_action No No
|
|
104
|
+
safari-mv3 3 Yes No action None Yes Yes
|
|
105
|
+
safari-mv2 2 No Yes browser_action None No No
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 5.2 Manifest Structure Invariants
|
|
109
|
+
- **Chromium MV3:**
|
|
110
|
+
- `background.service_worker = "src/background/index.(ts|js)"`
|
|
111
|
+
- `action.default_popup = "src/popup/index.html"`
|
|
112
|
+
- `side_panel.default_path = "src/sidepanel/index.html"`
|
|
113
|
+
- `permissions` includes `"sidePanel"` when sidepanel feature is enabled.
|
|
114
|
+
- **Firefox MV3:**
|
|
115
|
+
- `background.scripts = ["src/background/index.(ts|js)"]`
|
|
116
|
+
- `action.default_popup = "src/popup/index.html"`
|
|
117
|
+
- `sidebar_action.default_panel = "src/sidepanel/index.html"`
|
|
118
|
+
- `browser_specific_settings.gecko.id = "<name>@example.com"`
|
|
119
|
+
- `browser_specific_settings.gecko.strict_min_version = "109.0"`
|
|
120
|
+
- Does NOT include `"sidePanel"` in `permissions`.
|
|
121
|
+
- **Firefox MV2:**
|
|
122
|
+
- `manifest_version = 2`
|
|
123
|
+
- `background.scripts = ["src/background/index.(ts|js)"]`, `background.persistent = false`
|
|
124
|
+
- `browser_action.default_popup = "src/popup/index.html"`
|
|
125
|
+
- `sidebar_action.default_panel = "src/sidepanel/index.html"`
|
|
126
|
+
- `browser_specific_settings.gecko.id = "<name>@example.com"`
|
|
127
|
+
- `browser_specific_settings.gecko.strict_min_version = "58.0"`
|
|
128
|
+
- No `action`, `host_permissions`, or `declarative_net_request` keys.
|
|
129
|
+
- **Content-Only Mode:**
|
|
130
|
+
- `manifest.content_scripts` is populated.
|
|
131
|
+
- Manifest contains no `background`, `action`, `browser_action`, `options_ui`, or UI entries.
|
|
132
|
+
- Contains no `permissions` array unless explicitly demanded.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 6. Build Pipelines: MV3 vs MV2
|
|
137
|
+
|
|
138
|
+
Generated projects employ dual-mode packaging:
|
|
139
|
+
|
|
140
|
+
### 6.1 MV3 Pipeline (CRXJS)
|
|
141
|
+
- Handled by `@crxjs/vite-plugin` (`crx({ manifest: manifestConfig, browser })`).
|
|
142
|
+
- Full support for Vite HMR in popup, options, sidepanel, and content scripts on Chromium.
|
|
143
|
+
- Dev command: `vite` (or `vite build --watch` for Firefox/Safari).
|
|
144
|
+
|
|
145
|
+
### 6.2 MV2 Pipeline (Custom Standalone Bundler)
|
|
146
|
+
- `@crxjs/vite-plugin` is designed strictly for Manifest V3. When an MV2 target is active, the project does NOT pass MV2 manifests to CRXJS.
|
|
147
|
+
- Instead, the generator writes `build/mv2.(ts|js)` and registers `buildMv2Plugin` in `vite.config`.
|
|
148
|
+
- Build behavior:
|
|
149
|
+
1. Compiles HTML entry points (`popup.html`, `options.html`, `devtools.html`, etc.) via Rollup inputs.
|
|
150
|
+
2. Compiles content scripts and background scripts as standalone IIFE bundles (`formats: ['iife']`) so they can execute in classic MV2 runtimes without ES module loading limitations.
|
|
151
|
+
3. Emits `dist/<target>/manifest.json` dynamically from `manifest.config`.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 7. Package Manager Resolution Priority
|
|
156
|
+
|
|
157
|
+
When `--pm` is not explicitly supplied, package manager detection follows this deterministic order:
|
|
158
|
+
|
|
159
|
+
1. `process.env.npm_config_user_agent`:
|
|
160
|
+
- Matches regex `/(npm|pnpm|yarn|bun)\/([^\s]+)/`.
|
|
161
|
+
- Confident: `true`.
|
|
162
|
+
2. `packageManager` field:
|
|
163
|
+
- Recursively scans parent directories for `package.json` with a valid `packageManager` entry (e.g. `pnpm@8.15.0`).
|
|
164
|
+
- Confident: `true`.
|
|
165
|
+
3. Single Lockfile:
|
|
166
|
+
- Recursively scans parent directories for lockfiles in priority: `bun.lock`/`bun.lockb` -> `pnpm-lock.yaml` -> `yarn.lock` -> `package-lock.json`.
|
|
167
|
+
- If exactly one type is found: Confident: `true`.
|
|
168
|
+
- If multiple competing lockfiles exist: picks highest priority with Confident: `false`.
|
|
169
|
+
4. Global Binary Path:
|
|
170
|
+
- Inspects `process.argv[1]` for known global tool paths (`.bun`, `pnpm/global`, `Roaming/npm`, etc.).
|
|
171
|
+
- Confident: `false`.
|
|
172
|
+
5. Bun Runtime Environment:
|
|
173
|
+
- `typeof (globalThis as any).Bun !== 'undefined'`.
|
|
174
|
+
- Confident: `false`.
|
|
175
|
+
6. Fallback:
|
|
176
|
+
- Default: `npm`.
|
|
177
|
+
- Confident: `false`.
|
|
178
|
+
|
|
179
|
+
When Confident is `false` in an interactive TTY session without `--pm`, the user is prompted to select their package manager with the detected value as the default.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 8. Generated Project Structure
|
|
184
|
+
|
|
185
|
+
### Full Mode (TypeScript)
|
|
186
|
+
```text
|
|
187
|
+
my-extension/
|
|
188
|
+
├── public/
|
|
189
|
+
│ ├── icons/ (16.png, 48.png, 128.png)
|
|
190
|
+
│ └── rules/rules.json (if DNR enabled)
|
|
191
|
+
├── src/
|
|
192
|
+
│ ├── background/index.ts (if background enabled)
|
|
193
|
+
│ ├── content/
|
|
194
|
+
│ │ ├── index.ts (if content enabled)
|
|
195
|
+
│ │ └── style.css (if css enabled)
|
|
196
|
+
│ ├── popup/
|
|
197
|
+
│ │ ├── index.html
|
|
198
|
+
│ │ ├── main.ts
|
|
199
|
+
│ │ └── style.css
|
|
200
|
+
│ ├── options/
|
|
201
|
+
│ │ ├── index.html
|
|
202
|
+
│ │ ├── main.ts
|
|
203
|
+
│ │ └── style.css
|
|
204
|
+
│ ├── sidepanel/
|
|
205
|
+
│ │ ├── index.html
|
|
206
|
+
│ │ ├── main.ts
|
|
207
|
+
│ │ └── style.css
|
|
208
|
+
│ ├── devtools/
|
|
209
|
+
│ │ ├── devtools.html
|
|
210
|
+
│ │ ├── devtools.ts
|
|
211
|
+
│ │ └── panel.html
|
|
212
|
+
│ ├── newtab/
|
|
213
|
+
│ │ ├── index.html
|
|
214
|
+
│ │ ├── main.ts
|
|
215
|
+
│ │ └── style.css
|
|
216
|
+
│ └── lib/
|
|
217
|
+
│ ├── browser.ts (Universal API accessor)
|
|
218
|
+
│ └── storage.ts (if storage extra enabled)
|
|
219
|
+
├── build/
|
|
220
|
+
│ └── mv2.ts (present if any target is MV2)
|
|
221
|
+
├── env.d.ts
|
|
222
|
+
├── manifest.config.ts
|
|
223
|
+
├── targets.config.ts
|
|
224
|
+
├── vite.config.ts
|
|
225
|
+
├── tsconfig.json
|
|
226
|
+
├── tsconfig.app.json
|
|
227
|
+
├── tsconfig.background.json (isolated worker types)
|
|
228
|
+
├── tsconfig.node.json
|
|
229
|
+
├── package.json
|
|
230
|
+
├── .gitignore
|
|
231
|
+
└── README.md
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Content-Only Mode (TypeScript)
|
|
235
|
+
```text
|
|
236
|
+
my-extension/
|
|
237
|
+
├── public/
|
|
238
|
+
│ └── icons/ (16.png, 48.png, 128.png)
|
|
239
|
+
├── src/
|
|
240
|
+
│ ├── content/
|
|
241
|
+
│ │ ├── index.ts (DOM Hack / MutationObserver)
|
|
242
|
+
│ │ └── style.css (if css enabled)
|
|
243
|
+
│ └── lib/
|
|
244
|
+
│ └── browser.ts
|
|
245
|
+
├── env.d.ts
|
|
246
|
+
├── manifest.config.ts
|
|
247
|
+
├── targets.config.ts
|
|
248
|
+
├── vite.config.ts
|
|
249
|
+
├── tsconfig.json
|
|
250
|
+
├── tsconfig.app.json
|
|
251
|
+
├── tsconfig.node.json
|
|
252
|
+
├── package.json
|
|
253
|
+
├── .gitignore
|
|
254
|
+
└── README.md
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 9. Verification & Invariant Testing
|
|
260
|
+
|
|
261
|
+
Automated testing must verify:
|
|
262
|
+
1. `bun run typecheck`: Strict compilation across all sources without errors.
|
|
263
|
+
2. `bun run test`: Vitest unit tests verifying arg parsing, validation, targets, manifests, and package manager heuristics.
|
|
264
|
+
3. `bun run test:smoke`: End-to-end smoke test suite executing five suites:
|
|
265
|
+
- Suite A: Chromium MV3 (Full features, TS, DNR, extras).
|
|
266
|
+
- Suite B: Firefox MV2 (JS, background scripts, `build/mv2`).
|
|
267
|
+
- Suite C: Multi-browser (Chrome MV3, Firefox MV3, Safari MV2).
|
|
268
|
+
- Suite D: Content-only TS (Chrome, Firefox).
|
|
269
|
+
- Suite E: Content-only JS (Firefox MV2).
|
|
270
|
+
|
package/DEVELOPER.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Developer Guide: web-extension
|
|
2
|
+
|
|
3
|
+
This guide provides instructions and architectural details for developers contributing to the `web-extension` CLI.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Architecture Overview
|
|
8
|
+
|
|
9
|
+
The codebase is organized into four main layers:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
src/
|
|
13
|
+
├── index.ts CLI entry point and top-level error handler
|
|
14
|
+
├── cli/
|
|
15
|
+
│ ├── args.ts CLI flag parsing, aliases, and combination validation
|
|
16
|
+
│ ├── context.ts Shared TypeScript types, flags, and context interfaces
|
|
17
|
+
│ └── prompts.ts Interactive prompts (@clack/prompts) and cancel handling
|
|
18
|
+
├── generate/
|
|
19
|
+
│ ├── copy.ts Template file copier, placeholder injector, and file renamer
|
|
20
|
+
│ ├── index.ts Main project generation coordinator
|
|
21
|
+
│ ├── manifest.ts Manifest V3 and Manifest V2 generator per target browser
|
|
22
|
+
│ ├── pkgjson.ts Dynamic package.json builder with target dependencies
|
|
23
|
+
│ ├── targets.ts Browser capability matrix and target resolver
|
|
24
|
+
│ └── tsconfig.ts TypeScript (tsconfig) and JavaScript (jsconfig) builder
|
|
25
|
+
└── utils/
|
|
26
|
+
├── exec.ts Process execution, git detector, and command checks
|
|
27
|
+
├── pm.ts Multi-stage package manager detection heuristics
|
|
28
|
+
└── validate.ts Validation for npm package names, URLs, and match patterns
|
|
29
|
+
templates/
|
|
30
|
+
├── base/ Shared assets (icons, gitignore)
|
|
31
|
+
├── features/ Feature-specific templates (background, content, popup, etc.)
|
|
32
|
+
├── js/ JavaScript library utilities
|
|
33
|
+
└── ts/ TypeScript library utilities
|
|
34
|
+
test/ Vitest unit test suites
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. Prerequisites & Toolchain
|
|
40
|
+
|
|
41
|
+
- **Node.js:** `>= 20.0.0`
|
|
42
|
+
- **Bun:** `>= 1.0.0` (Bun is the designated package manager and runtime for this repository)
|
|
43
|
+
- **Bundler:** `tsup` compiling `src/index.ts` to `dist/index.js` as an ES Module targeting `node20`.
|
|
44
|
+
- **Testing:** `vitest` for fast unit tests, and Node/Bun runner for end-to-end smoke tests.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 3. Development Workflow
|
|
49
|
+
|
|
50
|
+
### 3.1 Install Dependencies
|
|
51
|
+
```bash
|
|
52
|
+
bun install
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3.2 Watch Mode (Active Development)
|
|
56
|
+
```bash
|
|
57
|
+
bun run dev
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3.3 Build Production Bundle
|
|
61
|
+
```bash
|
|
62
|
+
bun run build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3.4 Typecheck
|
|
66
|
+
```bash
|
|
67
|
+
bun run typecheck
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3.5 Run Unit Tests
|
|
71
|
+
```bash
|
|
72
|
+
bun run test
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 3.6 Run Smoke Tests
|
|
76
|
+
The smoke test suite verifies real extension generation, dependency installation, typechecking, and multi-browser builds across five distinct configurations:
|
|
77
|
+
```bash
|
|
78
|
+
bun run test:smoke
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 4. Coding Conventions & Standards
|
|
84
|
+
|
|
85
|
+
- **TypeScript Strictness:** Strict mode is enforced in `tsconfig.json`. Do not disable strict checks or introduce untyped `any` without explicit justification.
|
|
86
|
+
- **Documentation:** Use JSDoc / TSDoc comments for exported functions, types, and interfaces. Avoid inline step comments or temporary notes in source files.
|
|
87
|
+
- **No Decorative Symbols:** Do not use emojis, stickers, or decorative symbols in source code, console messages, or documentation.
|
|
88
|
+
- **Binary Shebang:** The shebang `#!/usr/bin/env node` is declared at the top of `src/index.ts`. Do not duplicate it via bundler banners.
|
|
89
|
+
- **Cross-Platform Compatibility:** Always handle Windows path separators and PowerShell execution nuances. For example, test file operations using `node:path` methods rather than hard-coded `/` or `\`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 5. Adding New Features or Browser Targets
|
|
94
|
+
|
|
95
|
+
To extend the CLI with a new extension capability:
|
|
96
|
+
|
|
97
|
+
1. **Context & Types (`src/cli/context.ts`):**
|
|
98
|
+
- Add new feature or extra keys to `FeatureKey` or `ExtraKey`.
|
|
99
|
+
2. **Capability Matrix (`src/generate/targets.ts`):**
|
|
100
|
+
- Define whether the feature is supported by each browser target in `CAPABILITY_MATRIX`.
|
|
101
|
+
3. **Manifest Generator (`src/generate/manifest.ts`):**
|
|
102
|
+
- Add the necessary manifest fields (permissions, keys, resources) for both MV3 and MV2.
|
|
103
|
+
4. **Template Files (`templates/features/<feature>/`):**
|
|
104
|
+
- Provide template implementations for both TypeScript and JavaScript.
|
|
105
|
+
5. **CLI Options (`src/cli/args.ts` & `src/cli/prompts.ts`):**
|
|
106
|
+
- Expose the corresponding CLI flags in `parseCliArgs` and help text.
|
|
107
|
+
- Add the interactive prompt option with support for skipping when the flag is supplied.
|
|
108
|
+
6. **Tests (`test/`):**
|
|
109
|
+
- Add unit tests verifying argument parsing and manifest generation.
|
|
110
|
+
- Update `test-smoke.mjs` to validate end-to-end bundling.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 6. Publishing Notes
|
|
115
|
+
|
|
116
|
+
- **Package Verification:** Before publishing to npm, verify package contents and permissions:
|
|
117
|
+
```bash
|
|
118
|
+
npm publish --dry-run
|
|
119
|
+
```
|
|
120
|
+
- **Automated Publishing:** A GitHub Actions workflow is configured at `.github/workflows/publish.yml` to automatically build, test, and publish to npm with `--provenance --access=public` whenever a new GitHub Release is published (`on: release`). Ensure the repository secret `NPM_TOKEN` is set up with publish permissions on npmjs.org.
|
|
121
|
+
- **Unpublish History:** The package name `web-extension` has past unpublish records on the npm registry. Do not attempt live publishing without explicit clearance from the repository owner.
|
|
122
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TiwPhiraphan
|
|
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
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
-
#
|
|
1
|
+
# web-extension
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Modern, flexible CLI tool to scaffold cross-browser extensions for Chromium (Chrome, Edge, Brave, Opera), Firefox, and Safari using **Vite** and **CRXJS**.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
- [Developer Guide](DEVELOPER.md) — Architecture, local development, testing, and contribution instructions.
|
|
10
|
+
- [AI & Agent Specification](AI.md) — Complete behavioral contracts, machine-readable specifications, and capability matrices for AI agents and LLMs.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Vite + CRXJS:** Ultra-fast bundling, live reloading, and HMR (Hot Module Replacement) where supported.
|
|
17
|
+
- **Cross-Browser:** Supports Chromium (MV3), Firefox (MV3 & MV2), and Safari (MV3 & MV2).
|
|
18
|
+
- **Modular Components:** Choose only what you need (Background service worker, Content scripts, Popup, Options page, Side panel, DevTools page, New Tab override, declarativeNetRequest rules).
|
|
19
|
+
- **Content-Script Only Mode:** Purpose-built mode for DOM scrapers and injectors without unnecessary UI files.
|
|
20
|
+
- **Automatic Type & Package Setup:** Installs browser-specific types (`@types/chrome`, `@types/firefox-webext-browser`) and auto-configures TypeScript (`tsconfig`) or JavaScript (`jsconfig`).
|
|
21
|
+
- **Smart Package Manager Detection:** Automatically detects whether you ran via `bun`, `pnpm`, `npm`, or `yarn`.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
Run the interactive generator using your preferred package manager:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# npm
|
|
31
|
+
npx web-extension@latest init
|
|
32
|
+
|
|
33
|
+
# pnpm
|
|
34
|
+
pnpm dlx web-extension@latest init
|
|
35
|
+
|
|
36
|
+
# bun
|
|
37
|
+
bun x web-extension@latest init
|
|
38
|
+
# or bunx
|
|
39
|
+
bunx web-extension@latest init
|
|
40
|
+
|
|
41
|
+
# yarn (Yarn 2+)
|
|
42
|
+
yarn dlx web-extension@latest init
|
|
43
|
+
|
|
44
|
+
# Or install globally
|
|
45
|
+
npm install -g web-extension
|
|
46
|
+
web-extension init
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> **Windows + Bun:** On some Windows systems, `bunx` may not be registered in PowerShell by default. Use `bun x web-extension@latest init` instead.
|
|
50
|
+
>
|
|
51
|
+
> **Shortcut:** Invoking `web-extension` without a subcommand automatically routes to `init`. For example, `web-extension my-app` is equivalent to `web-extension init my-app`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Interactive Prompts & Flags
|
|
56
|
+
|
|
57
|
+
Every interactive prompt has a corresponding CLI flag to enable scripted and non-interactive execution.
|
|
58
|
+
|
|
59
|
+
| # | Prompt | Flag | Options / Accepted Values | Default (`--yes`) |
|
|
60
|
+
|---|---|---|---|---|
|
|
61
|
+
| 1 | Project name | `[dir]`, `--name <string>` | Target directory and npm package name | `my-extension` |
|
|
62
|
+
| 1b | Directory not empty | `--if-exists <action>`, `--overwrite` | `cancel`, `overwrite`, `merge` | `cancel` |
|
|
63
|
+
| 2 | Language | `--lang <ts\|js>` | `ts` (TypeScript), `js` (JavaScript) | `ts` |
|
|
64
|
+
| 3 | Project type | `--type <full\|content-only>` | `full`, `content-only` | `full` |
|
|
65
|
+
| 4 | Target browsers | `--browser <browsers>` | `chrome`, `firefox`, `safari` (comma-separated or repeated) | `chrome` |
|
|
66
|
+
| 5 | Manifest version (Firefox) | `--firefox-mv <2\|3>` | `2`, `3` | `3` |
|
|
67
|
+
| 5b | Manifest version (Safari) | `--safari-mv <2\|3>` | `2`, `3` | `3` |
|
|
68
|
+
| 6 | Features (Full mode) | `--features <list>` | `background`, `content`, `popup`, `options`, `sidepanel`, `dnr`, `devtools`, `newtab` (or `none`) | `background,content` |
|
|
69
|
+
| 7 | Content script: matches | `--matches <patterns>` | Comma-separated match patterns (`https://*/*`, etc.) | `https://*/*` |
|
|
70
|
+
| 7 | Content script: run_at | `--run-at <timing>` | `document_start`, `document_end`, `document_idle` | `document_idle` |
|
|
71
|
+
| 7 | Content script: world | `--world <world>` | `ISOLATED`, `MAIN` (MV3 only) | `ISOLATED` |
|
|
72
|
+
| 7 | Content script: CSS | `--css` / `--no-css` | Generate CSS stylesheet for content script | `--css` |
|
|
73
|
+
| 8 | Extras | `--extras <list>` | `contextmenu`, `commands`, `omnibox`, `storage` (or `none`) | `none` |
|
|
74
|
+
| 9a | Package manager | `--pm <pm>` | `npm`, `pnpm`, `yarn`, `bun` | Auto-detected |
|
|
75
|
+
| 9 | Install dependencies | `--install` / `--no-install` | Automatically run install | `--install` |
|
|
76
|
+
| 10 | Git repository | `--git` / `--no-git` | Initialize git repo | `--git` |
|
|
77
|
+
| - | Accept defaults | `--yes`, `-y` | Use defaults for any omitted options | - |
|
|
78
|
+
| - | Help | `--help`, `-h` | Display help message and options | - |
|
|
79
|
+
| - | Version | `--version`, `-v` | Display version | - |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Common Recipes
|
|
84
|
+
|
|
85
|
+
### 1. Full Chromium TypeScript Extension
|
|
86
|
+
```bash
|
|
87
|
+
web-extension my-chrome-ext --lang ts --browser chrome \
|
|
88
|
+
--features background,content,popup,options,sidepanel,dnr \
|
|
89
|
+
--extras storage,commands --yes
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Firefox Manifest V2 JavaScript Extension
|
|
93
|
+
```bash
|
|
94
|
+
web-extension my-firefox-ext --lang js --browser firefox --firefox-mv 2 \
|
|
95
|
+
--features background,content,popup,options --yes
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Headless Content-Script DOM Hacker
|
|
99
|
+
```bash
|
|
100
|
+
web-extension dom-injector --type content-only --browser chrome,firefox \
|
|
101
|
+
--matches "https://*.github.com/*" --yes
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 4. Cross-Browser Extension (Chrome, Firefox, Safari)
|
|
105
|
+
```bash
|
|
106
|
+
web-extension multi-browser-ext --lang ts --browser chrome,firefox,safari \
|
|
107
|
+
--firefox-mv 3 --safari-mv 2 --features background,content,popup --yes
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Loading Your Extension into Browsers
|
|
113
|
+
|
|
114
|
+
After creating your project, enter the directory and start the dev server:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cd my-extension
|
|
118
|
+
npm run dev:chrome
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Chromium (Chrome, Edge, Brave, Opera)
|
|
122
|
+
1. Navigate to `chrome://extensions`.
|
|
123
|
+
2. Toggle on **Developer mode** in the top-right corner.
|
|
124
|
+
3. Click **Load unpacked** and select the `dist/chrome-mv3` folder inside your project.
|
|
125
|
+
|
|
126
|
+
### Firefox
|
|
127
|
+
1. Navigate to `about:debugging#/runtime/this-firefox`.
|
|
128
|
+
2. Click **Load Temporary Add-on...**.
|
|
129
|
+
3. Select the `manifest.json` file inside `dist/firefox-mv3` (or `dist/firefox-mv2`).
|
|
130
|
+
|
|
131
|
+
### Safari
|
|
132
|
+
Convert the compiled web extension output into an Xcode project using Apple's built-in converter:
|
|
133
|
+
```bash
|
|
134
|
+
xcrun safari-web-extension-converter dist/safari-mv3
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
[MIT](LICENSE)
|