diff --git a/packages/extension/.eslintrc.cjs b/packages/extension/.eslintrc.cjs
index c747e0b88..8885bc716 100644
--- a/packages/extension/.eslintrc.cjs
+++ b/packages/extension/.eslintrc.cjs
@@ -19,5 +19,14 @@ module.exports = {
project: ['./tsconfig.scripts.json'],
},
},
+
+ {
+ files: ['src/**/*-trusted-prelude.js'],
+ rules: {
+ 'import-x/extensions': 'off',
+ 'import-x/no-unassigned-import': 'off',
+ 'import-x/no-unresolved': 'off',
+ },
+ },
],
};
diff --git a/packages/extension/src/background-trusted-prelude.js b/packages/extension/src/background-trusted-prelude.js
new file mode 100644
index 000000000..19405f97b
--- /dev/null
+++ b/packages/extension/src/background-trusted-prelude.js
@@ -0,0 +1,2 @@
+import './dev-console.js';
+import './endoify.js';
diff --git a/packages/extension/src/background.ts b/packages/extension/src/background.ts
index ddf252964..c22a61d42 100644
--- a/packages/extension/src/background.ts
+++ b/packages/extension/src/background.ts
@@ -1,6 +1,4 @@
-import './dev-console.js';
-import './endoify.js';
-
+import './background-trusted-prelude.js';
import type { ExtensionMessage } from './shared.js';
import { Command, makeHandledCallback } from './shared.js';
diff --git a/packages/extension/tsconfig.build.json b/packages/extension/tsconfig.build.json
index ab2ce37fb..9ce11ecb2 100644
--- a/packages/extension/tsconfig.build.json
+++ b/packages/extension/tsconfig.build.json
@@ -13,5 +13,9 @@
{ "path": "../shims/tsconfig.build.json" },
{ "path": "../streams/tsconfig.build.json" }
],
- "include": ["./src/**/*.ts", "./src/dev-console.js"]
+ "include": [
+ "./src/**/*.ts",
+ "./src/**/*-trusted-prelude.js",
+ "./src/dev-console.js"
+ ]
}
diff --git a/packages/extension/tsconfig.json b/packages/extension/tsconfig.json
index 060acd4ab..449869536 100644
--- a/packages/extension/tsconfig.json
+++ b/packages/extension/tsconfig.json
@@ -9,6 +9,14 @@
"skipLibCheck": true,
"types": ["chrome", "ses", "vitest", "vitest/jsdom"]
},
- "references": [{ "path": "../streams" }, { "path": "../test-utils" }],
- "include": ["./src/**/*.ts", "./src/dev-console.js"]
+ "references": [
+ { "path": "../streams" },
+ { "path": "../test-utils" },
+ { "path": "../shims" }
+ ],
+ "include": [
+ "./src/**/*.ts",
+ "./src/**/*-trusted-prelude.js",
+ "./src/dev-console.js"
+ ]
}
diff --git a/packages/extension/vite-plugins/html-trusted-prelude.ts b/packages/extension/vite-plugins/html-trusted-prelude.ts
new file mode 100644
index 000000000..89ebb3385
--- /dev/null
+++ b/packages/extension/vite-plugins/html-trusted-prelude.ts
@@ -0,0 +1,46 @@
+import { load as loadHtml } from 'cheerio';
+import { format as prettierFormat } from 'prettier';
+import type { Plugin } from 'vite';
+
+/**
+ * Vite plugin to insert the endoify script before the first script in the head element.
+ *
+ * @throws If the HTML document already references the endoify script or lacks the expected
+ * structure.
+ * @returns The Vite plugin.
+ */
+export function htmlTrustedPrelude(): Plugin {
+ const endoifyElement = '';
+
+ return {
+ name: 'ocap-kernel:html-trusted-prelude',
+ async transformIndexHtml(htmlString): Promise {
+ const htmlDoc = loadHtml(htmlString);
+
+ if (htmlDoc('script[src="endoify.ts"]').length > 0) {
+ throw new Error(
+ `HTML document should not reference "endoify.ts" directly:\n${htmlString}`,
+ );
+ }
+
+ if (htmlDoc('script[src="endoify.js"]').length > 0) {
+ throw new Error(
+ `HTML document already references endoify script:\n${htmlString}`,
+ );
+ }
+
+ if (htmlDoc('head').length !== 1 || htmlDoc('head > script').length < 1) {
+ throw new Error(
+ `Expected HTML document with a single containing at least one ';
-
- return {
- name: 'externalize-plugin',
- async transformIndexHtml(htmlString): Promise {
- const htmlDoc = loadHtml(htmlString);
-
- if (htmlDoc('script[src="endoify.ts"]').length > 0) {
- throw new Error(
- `HTML document should not reference "endoify.ts" directly:\n${htmlString}`,
- );
- }
-
- if (htmlDoc('script[src="endoify.js"]').length > 0) {
- throw new Error(
- `HTML document already references endoify script:\n${htmlString}`,
- );
- }
-
- if (htmlDoc('head').length !== 1 || htmlDoc('head > script').length < 1) {
- throw new Error(
- `Expected HTML document with a single containing at least one