Skip to content

docs(frontend): add Frontend section (BE↔FE bridge, Web Host, authoring)#6

Draft
AndrewKirkovski wants to merge 21 commits into
mainfrom
docs/frontend-section
Draft

docs(frontend): add Frontend section (BE↔FE bridge, Web Host, authoring)#6
AndrewKirkovski wants to merge 21 commits into
mainfrom
docs/frontend-section

Conversation

@AndrewKirkovski

@AndrewKirkovski AndrewKirkovski commented Jun 2, 2026

Copy link
Copy Markdown

Summary

Adds a new Frontend documentation section under en/frontend/, integrating the previously-undocumented Wippy FE ecosystem into the docs site. Wires it into en/manifest.json and updates the two existing FE-adjacent framework docs (views.md, facade.md) to the current model.

Structure (three layers)

  • BE → FE Bridge — registry entries, view.page, view.component, dynamic routing
  • Web Host — overview, facade entry point, bootstrap, multi-panel layout, proxy & isolation, CSS injection, @wippy-fe packages
  • Writing Wippy FE — page apps, web components, proxy API, theming (common + page-app + web-component), build system, host-less mode, compliance checklist, debugging

Diagrams

10 diagrams rendered with beautiful-mermaid. Both .mmd source and generated .svg live together under en/frontend/diagrams/ (regenerate via the tool in .local/diagrams/). Includes separate diagrams for the two embedding paths: facade JS-module flow and manual iframe @gen2-chat handshake.

Accuracy

Key facts verified against the unpacked wippy/views vendor source:

  • The facade delivers the Web Host via module.js / managed-layout.js (takes over the page) — not an iframe shell. iframe.html + SetConfig PostMessage is the manual, facade-less embedding path.
  • fe_mode is a current facade parameter (compat default, managed early-access).
  • Proxy injection: package.json camelCase (author default) + YAML proxy: snake_case (operator override); host normalizes, YAML wins.
  • view.component announced and auto_register both default false.

Notes

  • English (en/) only for now; other languages deferred until content is stable.
  • Local preview is docsify (relativePath: true); links are file-relative. Dev artifacts (en/index.html, en/_sidebar.md, .local/, .cache/) are gitignored.

Opened as draft for review.

… and authoring

Adds a new `en/frontend/` documentation section with three layers:

- BE → FE Bridge: registry entries, view.page, view.component, dynamic routing
- Web Host: overview, facade entry point, bootstrap, multi-panel layout,
  proxy & isolation, CSS injection, @wippy-fe packages
- Writing Wippy FE: page apps, web components, proxy API, theming
  (common + page-app + web-component), build system, host-less mode,
  compliance checklist, debugging

Also includes 10 beautiful-mermaid diagrams (.mmd source + .svg) and wires
the section into en/manifest.json. Updates framework/views.md and
framework/facade.md to the current model (facade loads a JS module that
takes over the page; iframe.html is the manual facade-less embedding path)
and cross-links them to the new Frontend docs.

Key facts verified against the wippy/views vendor source:
- facade delivers via module.js / managed-layout.js (not an iframe shell)
- fe_mode is current (compat default, managed early-access)
- proxy injection: package.json camelCase + YAML proxy: snake_case override,
  host normalizes, YAML wins
- view.component announced & auto_register both default false
Updates the section title in the manifest nav, the overview headings and
cross-link, and the dynamic-routing diagram alt text. Folder path
(be-fe-bridge/) is unchanged.
…ntends)

Renames the FE docs vocabulary to a micro-frontend-native model so the
pipeline reads cleanly: Frontend Facade -> Wippy Web Host ->
(Micro Frontend Apps + Web Components).

- "Backend-Frontend Bridge" -> "Frontend Registry" (it's the wippy/views
  registry, not a facade synonym); folder be-fe-bridge/ -> frontend-registry/
- "Writing Wippy FE" -> "Wippy Micro Frontends"; folder writing-fe/ ->
  micro-frontends/
- "page app" -> "micro frontend app" in prose; page-app.md ->
  micro-frontend-app.md, page-app-theming.md -> micro-frontend-app-theming.md,
  wc-theming.md -> web-component-theming.md
- Manifest titles/paths, all cross-links, and the fe-arch-overview +
  frontend-registry diagrams updated to match; diagrams regenerated.

Literal API/code nouns (view.page, view.component, /api/public/pages/list,
mountRoute, WPage) and the host.bridge channel API are left untouched. The
registry section keeps view-page.md/view-component.md since they document the
literal entry types. All links validated; manifest is valid JSON.
Independent review pass after the Set A terminology rename. Fixes:

- Catch mixed-case "Page app"/"Page apps" that the case-sensitive first
  pass missed (~18 across overview, proxy-api, packages, compliance,
  micro-frontend-app). This also realigns the compliance-checklist §3 TOC
  anchor with its heading.
- view-page.md / view-component.md H1 headings → "Micro Frontend Apps
  (view.page)" / "Web Components (view.component)" to match the manifest.
- bootstrap.md: PostMessage example uses the wire value `set-config`
  (was the enum name `SetConfig`).
- facade.md: de-contradict the `fe_entry_path` row (scope it to the iframe
  embedding mode; the current facade loads the JS-module entry).
- views.md: clarify the registry-entry frontends bullet (was conflating
  view.page apps and view.component web components).
- css-injection.md: stale cross-ref label "Pages (view.page)" → "Micro
  Frontend Apps (view.page)".
- host-less-mode.md: note customCss/customVariables are enabled by default
  (so apps relying only on overrides misleadingly appear to work).

Confirmed false positives from the review (no change): apiRoutes appears in
both AppConfig (top-level) and HostConfig per source; package.json wippy.type
is correctly "page". All links validated; manifest valid; TOC anchors match.
…ade facts

- Standardize all Web Host CDN URLs to the `<release-tag>` placeholder
  (the deploy path is /<git-release-tag>/; docs previously showed three
  different example tags). Drops concrete version examples.
- facade.md: `session_type` corrected to `non-persistent | cookie` framed
  as auth-token storage (was wrongly "persistent" / "chat session
  persistence"). Verified against gen-2-chat types.ts + lib.ts.
- facade.md: `fe_facade_url` default shown as the `<release-tag>` placeholder.
- web-host/overview.md: simplify the CDN tag explanation.

Verified-correct, no change: `@gen2-chat` is the real default message type
(IFRAME_MESSAGE_TYPE = … || '@gen2-chat'); hostConfig.session.type values
are non-persistent|cookie. All links validated; manifest valid.
New quickstart page with two minimal end-to-end examples drawn from the
public wippyai/app-template repo:
- a Vue Micro Frontend App (view.page): package.json wippy block, getWippyApi
  bootstrap with mandatory route sync, and the _index.yaml registration.
- a Vue Web Component (view.component): reaction-bar — WippyVueElement +
  define(import.meta.url, …), useComponentProps/useComponentEvents, and the
  _index.yaml autoload registration.

Each links to the full source on github.com/wippyai/app-template and to the
deep-dive scaffold docs. Includes an "explore more" table of the repo's other
web component samples. Wired into the manifest (after Overview) and linked
from the section overview.
…ints table

The "Entry" and "URL path" columns were identical (module.js / /module.js).
Removed the URL-path column and added a one-line note that entries are served
at <release-tag>/<entry>.
…odule

Reframe the CDN versioning note: you normally don't set fe_facade_url — the
wippy/facade module ships pointing at a matching Web Host build, so the Web
Host version moves with facade updates. To pin a specific version, override
fe_facade_url, with a link to the CLI override (-o/--override) reference.
Update the Multi-Panel Layout minimum-version table (Web Host 1.0.38,
facade 1.0.38, @wippy-fe/* 0.0.38) and the minimum pin example to
webcomponents-1.0.38.
…/proxy

The docs described "two proxy adapters" and bootstrapped apps with
`await getWippyApi()` imported from @wippy-fe/proxy. Both are wrong (verified
against gen-2-chat source):

- There is ONE runtime (proxy.js). @wippy-fe/proxy is a thin SYNC facade that
  re-exports sync getters (host, api, on, config, state, ws, logger, …) reading
  the globals proxy.js installs. It does NOT export getWippyApi or instance.
- Config is injected synchronously (host writes window.__WIPPY_APP_CONFIG__
  before proxy.js in the child srcdoc), for both view.page and view.component —
  so child code uses sync imports, no handshake.
- window.$W / getWippyApi / window.__WIPPY_* are internal globals.

Changes:
- proxy-isolation.md: replace "Two Proxy Adapters" with one-runtime model;
  reframe page-app-vs-WC differences as execution context + CSS delivery; add an
  "Internals — do not read or override" table; frame the PostMessage protocol as
  internal transport (manual ?waitForCustomConfig path only).
- proxy-api.md: rewrite to sync @wippy-fe/proxy imports across the whole
  reference; drop the $W/getWippyApi init; add an Internals note.
- packages.md: unify the access table (both kinds use sync @wippy-fe/proxy);
  fix the @wippy-fe/proxy description.
- micro-frontend-app.md + quickstart.md: sync-import bootstrap (no getWippyApi/
  await; on() not instance.on); drop the WIPPY_INSTANCE/useWippy provide/inject.
- mention sweep across web-component, host-less-mode, debugging,
  compliance-checklist, view-component, overview.
- proxy-layers diagram redrawn to the one-runtime model; regenerated.

The two official surfaces are documented as initWippyApp(config) (mounts the
whole Web Host — facade/module embed) and @wippy-fe/proxy (sync child API).
All links validated; diagrams regenerated.
Redraw the Proxy & Isolation diagram as a clear loop: Web Host injects
the Proxy API → child (MFE app / web component) uses it → child can host
more children via <w-iframe>/<w-artifact>/html.inject, re-injecting the
runtime, nesting indefinitely.

proxy-isolation.md:
- add a "Composition & nesting" section — any node hosts MFE/WC children;
  iframe children need the runtime injected by the primitives, web
  components just import the Proxy API (no preprocessing)
- drop the wrong "web component = leaf node" row from the differences table
- correct two anchor links to docsify's actual slugs (<>→lt/gt)

Tone pass across the proxy docs: present the current Proxy API plainly
instead of narrating a corrected/historical model — "One runtime, one
API" → "The Proxy API", "What actually differs" → "How apps and web
components differ", drop "was the facade's previous default / no longer
used / two official surfaces" framing in overview, entry-point, packages,
and proxy-api.
The <w-iframe>/<w-artifact> links in proxy-isolation.md's Composition &
nesting section now use GitHub/standard-markdown anchor form
(#w-iframe-custom-element), matching the convention used throughout the
repo, instead of docsify's local-preview-specific slug.
…licts)

Audited the FE docs against gen-2-chat / app-template-raw source + KB via an
agent swarm; this applies the 24 verified fixes (one agent per file).

Notable source-contradictions corrected:
- host-less-mode.md / debugging.md documented a non-existent global
  `window.__WIPPY_PROXY__` (incl. a vitest stub) → real global is
  `window.__WIPPY_APP_API__`.
- css-injection.md: the 7 non-CSS injection flags default `true` at runtime,
  not `false`.
- Routing cluster (dynamic-routing.md, packages.md, multi-panel-layout.md):
  real LinkKind set is host-nav/child-nav/external/ignore (not spa/reload);
  CmdRouteChanged payload is `internalRoute` over the @gen2-chat envelope;
  host calls router.push (not replace); createAppRouter(routes, options?) is
  positional; no AppRouterLink export; mountRoute accepts only the v1
  catch-all form.
- packages.md: useComponentEvents() returns a callable emit; root via
  `static get vueConfig()`; import map completed.
- proxy-isolation.md: artifact endpoint is /api/v1/artifact/<id>/content;
  <w-iframe> does set a status attribute.
- view-component.md: YAML meta.tag_name wins (bundled tagName is fallback).
- entry-point.md/facade.md: apiRoutes & axiosDefaults are top-level AppConfig
  fields, not under hostConfig.

Owner-decided conflicts:
- overview.md renumbered to the runtime model (Facade=L1, Web Host=L2,
  Micro Frontends=L3); wippy/views Registry moved to its own section.
- views.md: proxy injection CAN be overridden via the snake_case YAML
  `proxy:` block and YAML wins per flag.
- facade.md: history_mode values are hash/browser.

Plus terminology/cross-link and clarity fixes (U1–U4) and the
mountroute-sync diagram label (onRouteChanged second arg is navId).
Question-coverage audit: 36/48 questions answered correctly; this fixes
the 11 gaps (Q4, Q12-Q13, Q15, Q19, Q21, Q37, Q45-Q47, Q3). Q11 skipped
per the owner's P1 decision (YAML proxy override is canonical).

Q4 (compile-breaking, verified against source): the documented
`import type { HostApi, ProxyApiInstance, AppConfig } from '@wippy-fe/shared'`
does not exist — none are exported by @wippy-fe/shared or @wippy-fe/proxy.
They are ambient types from @wippy-fe/types-global-proxy (tsconfig "types");
HostApi = ProxyApiInstance['host']. proxy-api.md/packages.md now point at
the ambient package; the two local types.ts examples
(compliance-checklist.md, micro-frontend-app.md) derive named aliases at
the type level from window.$W (typeof only — no runtime read), matching the
shipped app-template. A grep caught two instances the question-sampling
missed.

Other source-contradictions corrected:
- web-component.md: WippyVueElement does NOT pre-hydrate; pinia-persist
  hydrates async on first access (can flash initial state).
- registry docs: entry_point/tag_name are FE-authored (wippy.path /
  wippy.tagName) + YAML-overridable, not deploy-only.
- dynamic-routing.md: duplicate mountRoute is an HTTP-500 conflict, not
  "first wins, silently ignored".
- compliance-checklist.md: @light/@dark compile to prefers-color-scheme
  only, not [data-theme].
- css-injection.md: customCSS/cssVariables override via adoptedStyleSheets
  (not <head> order); customCSS wins over cssVariables.
- proxy-isolation.md: get-config/set-config also runs as a non-blocking
  re-sync on the standard path; nav-owner detail is the raw internal route
  and suppresses the host URL round-trip; host.bridge is one-handler-per-
  channel.
- build-system.md: set preserveEntrySignatures:false explicitly.
- debugging.md: @wippy-fe/proxy is import-mapped by the host, not
  globals-only.
…e refs)

Round 2 asked 25 fresh questions (avoiding round 1's 48) → 18 correct;
this fixes the 7 gaps, concentrated in the managed-layout / @wippy-fe
package-reference surface:

- multi-panel-layout.md: openModal IS shipped over the proxy (only
  addPanel/setLayout are not) — corrected the Known-Limitations claim and
  added an openModal row to the Layout API table; documented updatePanel
  merge semantics (props shallow-merges, other fields replace) with a
  before/after example; fixed the @wippy-fe/vue-host composables
  (useWippyPanel(panelId) required arg; composables never return null —
  guard via isManaged.value; module-scoped subscription, no per-component
  cleanup); removed the last stray `import type { ProxyApiInstance } from
  '@wippy-fe/proxy'` (ambient, no import).
- packages.md: useComponentProps/useComponentEvents are project-local
  wrappers, not @wippy-fe/webcomponent-vue exports (real: useProps/useEvents
  + useContent/useHost/usePanelId/useLayoutBus); same vue-host composable
  corrections; pinia-persist export is createWippyPersist (not
  createWippyPersistPlugin) and opt-in is wippyPersist:true (not
  persist:true), custom scope auto-prefixed @Custom:.
- proxy-isolation.md / proxy-api.md: host.bridge.request defaults to a 10s
  timeout (rejects "timed out after"); no-handler rejects immediately;
  annotated the updatePanel example pair.
Follow-up to the openModal fix: the layout/proxy command surface has two
orthogonal axes that the docs blurred — (1) exposed over the proxy vs
internal-only, and (2) takes effect in compat (default) vs managed mode.
Verified against gen-2-chat source.

multi-panel-layout.md:
- Corrected the misleading "consumer code using the proxy API is identical
  in both modes" — the surface is identical but the effect is mode-specific.
- New "What works in which mode" section:
  - host.layout is managed-only IN EFFECT: the host installs the layout
    receiver only when a layout is declared (managed-layout.ts gated on
    hostConfig.layout); in compat host.layout exists but snapshot is null and
    every mutation/bus call is a silent no-op. Gate on host.layout.snapshot /
    isManaged. (addPanel/setLayout are the separate not-over-proxy axis.)
  - host.* commands that assume the compat shell: openArtifact / startChat /
    openSession / navigate dispatch but have no rendering surface in the
    managed shell (it mounts only the declared layout — no nav/right-panel/
    modal/root RouterView, per ManagedLayoutShell.vue); setContext / toast /
    confirm / handleError / logout / bridge / state / ws / on are
    mode-agnostic (managed mounts Toast + ConfirmDialog deliberately);
    onRouteChanged works in both with different semantics.

proxy-api.md: added a managed-layout caveat note next to host.navigate
pointing to the new section. (host.layout already documented as managed-only.)
Reframed config_overrides theming around its actual purpose (owner-confirmed
+ source-verified): a page's cssVariables/customCSS override is merged into
that page's theming.global and PROPAGATES to everything the page embeds —
every nested child (<w-iframe>, <w-artifact>, html.inject) is built from the
page's already-merged config and inherits it, recursively (gen-2-chat
src/proxy/shared/html.ts:44-58 buildInjectedChildConfig -> buildChildPayload
with parentConfig as the base, nestingDepth++). So a module can ship pages
carrying their own theme (e.g. an admin UI) that cascades to its whole
sub-tree.

- micro-frontend-app-theming.md: fixed the incorrect "affects only the iframe
  that hosts that page — nothing else" (it themes the page AND its children).
- css-injection.md / proxy-api.md: broadened "nested <w-artifact> inherit" to
  all nested children, recursively, framed as the propagation point.
- compliance-checklist.md: reframed the "Per-page ISOLATION override only" /
  "isolation-only" framing to "per-page + sub-tree override" with the
  admin-module cascade as the typical use.
… CSS files

1. gold references: the `gold:` legend now resolves to the real repo
   (github.com/wippyai/app) with the path aliases verified against the
   tree — gold:main/ = frontend/applications/main/, gold:mermaid/ =
   frontend/web-components/mermaid/, others repo-root-relative. Normalized
   the two `gold:app-template/frontend/...` refs to the alias form. Also
   updated quickstart.md's repo links app-template -> app.

2. facade theming: added a tip to keep `custom_css` / `css_variables` in
   standalone files via `fs://` + `content_fs` (e.g. custom-css.facade.css /
   css-variables.facade.json in static/), co-located with the login_path
   page — so a non-Web-Host page like login.html can <link> the SAME brand
   CSS instead of duplicating it. Matches app-template's
   src/app/deps/_index.yaml:225-228 (fs:// not file://).
…eming

Follow-up: css_variables is JSON, so it can't be <link>ed directly. The
facade exposes it as generated CSS at GET /facade/variables.css (text/css
:root{} sheet, @dark/@light -> @media prefers-color-scheme, cached 1h,
registered on the same public router as /facade/config). Replaced the
earlier theming tip with a "Reusing facade theming on non-Web-Host pages"
subsection: keep custom_css/css_variables in fs:// files, and have a
standalone page like login.html link BOTH the /facade/variables.css
endpoint (css_variables) and the custom_css .css file. Added a discovery
cross-link from the Config Endpoint section.

Source: wippy/facade _index.yaml:367-373 (css_vars_endpoint),
css_vars_handler.lua, theming_helpers.build_variables_css.
Multi-agent structured review (dimensions + adversarial verify) over the FE
docs; this applies the 31 verified fixes (26 files). Highlights, all checked
against gen-2-chat / app-template source:

- R1: the mount-route endpoint /api/v2/views/pages/routes was FABRICATED →
  /api/public/pages/routes (dynamic-routing, view-page, bootstrap + the
  frontend-registry / bootstrap-iframe diagrams + SVGs).
- R2: the per-page proxy override is a camelCase `proxy:` block UNDER `meta:`,
  deep-merged over the bundled wippy.proxy (YAML wins per nested key) — NOT a
  snake_case sibling-of-meta block with "casing normalization". Corrected in
  view-page, css-injection, compliance-checklist. This also means the YAML
  override works, so the previously-logged "views ignores YAML proxy" was the
  wrong documented shape, not a views bug (retracted).
- F2: routePrefix is the API origin (PUBLIC_API_URL), not "/app" (reverted).
- css.fonts removed everywhere (not a real injection flag; Google Fonts ship
  via theming.global.customCSS @import).
- Versions aligned to shipped 1.0.36 / 0.0.36.
- API drift: host.on/host.state → top-level on/state; installVueWarnSuppressor(app);
  createAppRouter(routes) positional (+ dropped double route-sync wiring);
  loadByTagName for tag loads; quickstart webComponent() export; instance.on → on;
  host.navigate(url); host.layout is always a LayoutApi (snapshot is nullable).
- theming.md surface palette regenerated from theme-config.css (+ --p-surface-850);
  historyPolyfill marked a no-op; preserveEntrySignatures:false explicit;
  base_path is not page-only; views.md adds /components/by-tag + /pages/routes;
  dangling anchors + terminology + repo-link fixed.
…teness)

Round-1 fixes held (no regressions). Round 2 + a re-run of 6 lenses caught
13 remaining issues, all source-verified:

- views.md:148 STILL had the wrong snake_case / sibling-of-meta proxy shape
  (my R2 cleanup scoped to compliance-checklist + css-injection and missed
  views.md). Now camelCase `proxy:` under `meta:`, deep-merged, YAML wins per
  nested key — the last instance corpus-wide. Flagged by 4 lenses.
- en/frontend/overview.md was missed by every prior pass: Layer-3 "See:" link
  now points at micro-frontends/overview.md (matching its H1); "all 14
  packages" -> "every package" (there are 15 sections).
- Two re-read mediums (round-1 fix follow-ons): dynamic-routing.md Host->Child
  echoes the child's INTERNAL route (/profile, not /home/profile);
  multi-panel-layout.md drops the redundant manual on('@history') the
  createAppRouter factory already installs (with its echo guard).
- theming.md: --p-content-background is defined directly in theme-config.css
  (surface-0 light / surface-900 dark), not "via host".
- packages.md @wippy-fe/log: createChildLogger from the /logger subpath
  (createLogger isn't a root export; {name} isn't a valid option).
- proxy-api.md + compliance-checklist.md: add the @layout-breakpoint topic
  ({ name, width }).
- facade.md: login_path moved out of the Theming table into Configuration
  Parameters; config JSON adds login_redirect_param + extraScripts.
- views.md /components/list is announced+access-controlled; view-component.md
  define is imported from @wippy-fe/webcomponent-vue; micro-frontend-app.md
  clarifies the project-local createAppRouter wrapper vs the factory.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant