From 2094ba89301b6058e7601f2c0eb0ce7c3d376cf3 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 10:18:01 +0000 Subject: [PATCH 1/3] fix: copy WASM files to public/ instead of app/ in Docker build The WASM files (hp_ssh.wasm, wasm_exec.js) were being copied to /run/app/ which contains React Router source files that get compiled. Static assets need to be in /run/public/ so Vite copies them to build/client/ during the build, making them available at runtime via the Hono static file server. https://claude.ai/code/session_01E9a9GGxEPjEyMTRcbTrVmC --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7d16c657..6fa6c54a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,8 +32,8 @@ RUN corepack enable COPY patches ./patches COPY package.json pnpm-lock.yaml build.sh ./ -COPY --from=go-base /bin/hp_ssh.wasm /run/app/hp_ssh.wasm -COPY --from=go-base /bin/wasm_exec.js /run/app/wasm_exec.js +COPY --from=go-base /bin/hp_ssh.wasm /run/public/hp_ssh.wasm +COPY --from=go-base /bin/wasm_exec.js /run/public/wasm_exec.js RUN ./build.sh --app --app-install-only COPY . . From 11fc2988c5d220624d16e1279d0b30d46fe1db9b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 11:01:13 +0000 Subject: [PATCH 2/3] fix: use __PREFIX__ for wasm asset paths in SSH console The wasm_exec.js and hp_ssh.wasm files were referenced with absolute root paths (e.g. /wasm_exec.js) instead of using the __PREFIX__ global, causing them to fail when Headplane is served under a subpath like /admin. https://claude.ai/code/session_01E9a9GGxEPjEyMTRcbTrVmC --- app/routes/ssh/console.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/routes/ssh/console.tsx b/app/routes/ssh/console.tsx index 93f0260d..7bf9610c 100644 --- a/app/routes/ssh/console.tsx +++ b/app/routes/ssh/console.tsx @@ -19,7 +19,7 @@ export const shouldRevalidate: ShouldRevalidateFunction = () => { export async function loader({ request, context }: Route.LoaderArgs) { const origin = new URL(request.url).origin; - const assets = ["/wasm_exec.js", "/hp_ssh.wasm"]; + const assets = [`${__PREFIX__}/wasm_exec.js`, `${__PREFIX__}/hp_ssh.wasm`]; const missing: string[] = []; for (const file of assets) { @@ -180,7 +180,7 @@ export async function action({ request, context }: Route.ActionArgs) { export const links: Route.LinksFunction = () => [ { rel: "preload", - href: "/hp_ssh.wasm", + href: `${__PREFIX__}/hp_ssh.wasm`, as: "fetch", type: "application/wasm", crossOrigin: "anonymous", @@ -190,7 +190,7 @@ export const links: Route.LinksFunction = () => [ export const handle: ExternalScriptsHandle = { scripts: [ { - src: "/wasm_exec.js", + src: `${__PREFIX__}/wasm_exec.js`, crossOrigin: "anonymous", preload: true, }, @@ -211,7 +211,7 @@ export default function Page({ loaderData: { ipnDetails, sshDetails } }: Route.C pause(); const go = new Go(); // Go is defined by wasm_exec.js - WebAssembly.instantiateStreaming(fetch("/hp_ssh.wasm"), go.importObject).then((value) => { + WebAssembly.instantiateStreaming(fetch(`${__PREFIX__}/hp_ssh.wasm`), go.importObject).then((value) => { go.run(value.instance); const handle = TsWasmNet(ipnDetails, { NotifyState: (state) => { From b8bd498b58b628c2693c709b8af2fd1abb99d3c1 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Mar 2026 14:54:42 +0000 Subject: [PATCH 3/3] fix: deduplicate @codemirror/state to fix ACL editor crash @shopify/lang-jsonc pulled in @codemirror/state@6.5.4 while the rest of the codemirror packages used 6.6.0, causing "multiple instances of @codemirror/state" errors that broke the ACL editor. https://claude.ai/code/session_01E9a9GGxEPjEyMTRcbTrVmC --- package.json | 5 ++++- pnpm-lock.yaml | 30 +++++++++++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index d6cb5aef..404df400 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,9 @@ }, "ignoredBuiltDependencies": [ "better-sqlite3" - ] + ], + "overrides": { + "@codemirror/state": "6.6.0" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f71cb44..12b7343b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@codemirror/state': 6.6.0 + patchedDependencies: react-router-hono-server: hash: e94667f181837f2501959f5cf01fa0a9e6ea2883dcb1137be8b1c6178979bc77 @@ -476,7 +479,7 @@ packages: resolution: {integrity: sha512-wJGylKtMFR/Ds6Gh01+OovXE/pncPiKZNNBKuC39pKnH+XK5d9+WsNqcrdxPjFPFTigRBqse0rfxw9UxrfyhPg==} peerDependencies: '@codemirror/language': ^6.0.0 - '@codemirror/state': ^6.0.0 + '@codemirror/state': 6.6.0 '@codemirror/view': ^6.0.0 '@lezer/common': ^1.0.0 @@ -498,9 +501,6 @@ packages: '@codemirror/search@6.5.7': resolution: {integrity: sha512-6+iLsXvITWKHYlkgHPCs/qiX4dNzn8N78YfhOFvPtPYCkuXqZq10rAfsUMhOq7O/1VjJqdXRflyExlfVcu/9VQ==} - '@codemirror/state@6.5.4': - resolution: {integrity: sha512-8y7xqG/hpB53l25CIoit9/ngxdfoG+fx+V3SHBrinnhOtLvKHRyAJJuHzkWrR4YXXLX8eXBsejgAAxHUOdW1yw==} - '@codemirror/state@6.6.0': resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==} @@ -2635,7 +2635,7 @@ packages: '@codemirror/language': '>=6.0.0' '@codemirror/lint': '>=6.0.0' '@codemirror/search': '>=6.0.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.6.0 '@codemirror/view': '>=6.0.0' '@uiw/codemirror-theme-github@4.25.1': @@ -2648,21 +2648,21 @@ packages: resolution: {integrity: sha512-6o8tQ8bdq14RuVFpZ7l9u8KnuPq824uG3U1VV933Uhv8mfaxaoaOQSjv6T2bQUPhjH6ZlEu5+tAMkOfIL21eIQ==} peerDependencies: '@codemirror/language': '>=6.0.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.6.0 '@codemirror/view': '>=6.0.0' '@uiw/codemirror-themes@4.25.5': resolution: {integrity: sha512-mvNFy1eEkWTPSztL+N6cmOOZN26Wn9mGZUsFeIIRRkGqR4+Z9NBjzWF8JHqhZ73pEMOYe3UO+cRF/M9cxiTk9Q==} peerDependencies: '@codemirror/language': '>=6.0.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.6.0 '@codemirror/view': '>=6.0.0' '@uiw/react-codemirror@4.25.5': resolution: {integrity: sha512-WUMBGwfstufdbnaiMzQzmOf+6Mzf0IbiOoleexC9ItWcDTJybidLtEi20aP2N58Wn/AQxsd5Otebydaimh7Opw==} peerDependencies: '@babel/runtime': '>=7.11.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.6.0 '@codemirror/theme-one-dark': '>=6.0.0' '@codemirror/view': '>=6.0.0' codemirror: '>=6.0.0' @@ -4214,7 +4214,7 @@ packages: resolution: {integrity: sha512-P3U8TpOTEHR3wCQ1MmDSIF6BQrkjZiERA/pflcJjprnYTMCOZWYWaE7jFY7uYXnCVmWJrBTOvfRkNCstbvM/Iw==} peerDependencies: '@babel/runtime': '>=7.11.0' - '@codemirror/state': '>=6.0.0' + '@codemirror/state': 6.6.0 '@codemirror/theme-one-dark': '>=6.0.0' '@codemirror/view': '>=6.0.0' codemirror: '>=6.0.0' @@ -5346,7 +5346,7 @@ snapshots: '@codemirror/commands@6.10.2': dependencies: '@codemirror/language': 6.12.2 - '@codemirror/state': 6.5.4 + '@codemirror/state': 6.6.0 '@codemirror/view': 6.39.15 '@lezer/common': 1.5.1 @@ -5359,7 +5359,7 @@ snapshots: '@codemirror/language@6.12.2': dependencies: - '@codemirror/state': 6.5.4 + '@codemirror/state': 6.6.0 '@codemirror/view': 6.39.15 '@lezer/common': 1.5.1 '@lezer/highlight': 1.2.3 @@ -5375,7 +5375,7 @@ snapshots: '@codemirror/merge@6.12.0': dependencies: '@codemirror/language': 6.12.2 - '@codemirror/state': 6.5.4 + '@codemirror/state': 6.6.0 '@codemirror/view': 6.39.15 '@lezer/highlight': 1.2.3 style-mod: 4.1.3 @@ -5386,10 +5386,6 @@ snapshots: '@codemirror/view': 6.39.15 crelt: 1.0.6 - '@codemirror/state@6.5.4': - dependencies: - '@marijn/find-cluster-break': 1.0.2 - '@codemirror/state@6.6.0': dependencies: '@marijn/find-cluster-break': 1.0.2 @@ -5403,7 +5399,7 @@ snapshots: '@codemirror/view@6.39.15': dependencies: - '@codemirror/state': 6.5.4 + '@codemirror/state': 6.6.0 crelt: 1.0.6 style-mod: 4.1.3 w3c-keyname: 2.2.8