Zweistein Embedding Widget Local Runtime Slice
Date: 2026-05-05
Objective
Make the imported legacy zweistein/embedding-widget reproducible locally and prove that the static embed script can be built and served.
This slice covers the published-app embed surface: the script that external pages load to open Blinkin public apps in a floating or popover iframe.
What Was Added
configs/local/zweistein-embedding-widget.env.exampleLocal-only dev-server port for the widget.scripts/zweistein-embedding-widget-local.mjsSmall helper for install, build, dev server, health check, and artifact check.package.jsonscripts:zweistein-widget:installzweistein-widget:buildzweistein-widget:devzweistein-widget:healthzweistein-widget:artifact
No widget source behavior was changed in this slice.
Local Commands
Install dependencies:
npm run zweistein-widget:install
Build the widget:
npm run zweistein-widget:build
Check that the static embed artifact exists:
npm run zweistein-widget:artifact
Expected result:
Zweistein embedding widget artifact exists: legacy-src/zweistein/embedding-widget/dist/assets/emb-chat.js
Start the local widget dev server:
npm run zweistein-widget:dev
In another terminal, check the dev route:
npm run zweistein-widget:health
Expected result:
Zweistein embedding widget dev server responded on http://127.0.0.1:5177/
Verification Evidence
- Direct
npm ciinlegacy-src/zweistein/embedding-widgetcompleted. - Direct
npm run buildinlegacy-src/zweistein/embedding-widgetpassed. npm run zweistein-widget:installcompleted through the root helper.npm run zweistein-widget:buildpassed through the root helper.npm run zweistein-widget:artifactfounddist/assets/emb-chat.js.npm run zweistein-widget:devlaunched Vite onhttp://127.0.0.1:5177/.npm run zweistein-widget:healthreturned HTTP 200 for the local dev route.- The dev HTML still contains the expected
data-blinkin-url,BLINKIN_EMBEDDING_DATA, and/src/main.tsmarkers.
Current Artifact
The production build emits:
legacy-src/zweistein/embedding-widget/dist/assets/emb-chat.js
Current build size:
7.12 kB, gzip 2.40 kB
Important Findings
The legacy README says the widget deployment flow is:
- Build the widget.
- Copy the compiled JavaScript file from
distintoapps/houston/public/widget/main.js. - Deploy Houston.
That means this widget is not a standalone app in production. It is an asset that must be served by the public runtime that hosts published apps.
For the new Hetzner platform, we need to choose one of these paths:
- preserve the old Houston-hosted static asset path;
- serve the widget from the new frontend runtime;
- serve the widget from a dedicated static asset route or CDN.
Security And Maintenance Notes
npm ci reported 5 dependency vulnerabilities:
1 moderate, 4 high
No npm audit fix was applied in this slice, because that could upgrade dependencies and change legacy runtime behavior. This should be handled as a separate dependency-maintenance slice.
Not Yet Done
- The widget was not attached to a real locally published app, because no full local published-app flow exists yet.
- The iframe target URLs in the legacy demo HTML still point to old/local placeholder hosts.
- The widget artifact is not copied into a Houston or replacement runtime yet.
- Floating and popover behavior were not browser-click tested in this slice.
- The new Hetzner public asset path is not decided yet.