diff --git a/packages/extension/src/__tests__/build.test.ts b/packages/extension/src/__tests__/build.test.ts index 7d8ee8e..ee2e938 100644 --- a/packages/extension/src/__tests__/build.test.ts +++ b/packages/extension/src/__tests__/build.test.ts @@ -29,6 +29,11 @@ test('build: all targets produce loadable unpacked dirs with validated manifests const html = await readFile(join(r.dir, f), 'utf8'); assert.ok(html.includes('ui.js') && html.includes('style.css'), `${r.target}/${f} missing asset links`); } + // manifests reference icons; every referenced icon must be copied byte-for-byte + const icons = m.icons as Record; + for (const icon of Object.values(icons)) { + await readFile(join(r.dir, icon)); + } } // target delta is real: chromium has side_panel, firefox sidebar_action, safari neither const chromium = JSON.parse(await readFile(join(out, 'chromium', 'manifest.json'), 'utf8')); diff --git a/packages/extension/src/build.ts b/packages/extension/src/build.ts index 27b587b..e2a29b8 100644 --- a/packages/extension/src/build.ts +++ b/packages/extension/src/build.ts @@ -3,7 +3,7 @@ * * `hmh extension build --target=firefox` (or =all) writes a LOADABLE, * per-browser unpacked directory: the zero-build payload (background.js, - * popup/sidepanel HTML, ui.js, style.css) copied verbatim + a manifest + * popup/sidepanel HTML, ui.js, style.css, and icons) copied verbatim + a manifest * generated for the target from the adapters matrix, then machine- * validated (validateManifest) before the directory is declared done. * No bundler — same discipline as the web package's embedded SPA. @@ -13,7 +13,16 @@ import { fileURLToPath } from 'node:url'; import { join, resolve } from 'node:path'; import { EXTENSION_TARGETS, manifestFor, TARGET_SPECS, validateManifest, type ExtensionTarget } from './adapters.ts'; -export const PAYLOAD_FILES = ['background.js', 'popup.html', 'sidepanel.html', 'ui.js', 'style.css'] as const; +export const PAYLOAD_FILES = [ + 'background.js', + 'popup.html', + 'sidepanel.html', + 'ui.js', + 'style.css', + 'icon-48.png', + 'icon-96.png', + 'icon-128.png', +] as const; /** The zero-build payload directory inside this package (works from src/ * under tsx and from dist/ after tsc — both sit one level under the diff --git a/scripts/check-website.cjs b/scripts/check-website.cjs new file mode 100644 index 0000000..934bb72 --- /dev/null +++ b/scripts/check-website.cjs @@ -0,0 +1,65 @@ +/** + * Website guard (scripts/check-website.cjs) + * The marketing site (website/index.html) carries an inline i18n dictionary + * (zh/en) and inline JS. This gate catches, before merge: + * 1. a syntax error in any inline