188 lines
19 KiB
Markdown
188 lines
19 KiB
Markdown
# Custom Widget platform implementation
|
|
|
|
Approved direction: trusted React/TypeScript/CSS packages and optional supervised Node handlers, dashboard tiles and advanced views, a shared native/custom SDK, owner-enabled named guest controls, and self-hosted/offline distribution. Preserve v2 without silently elevating its trust.
|
|
|
|
## Delivery ledger
|
|
|
|
This branch delivers an operational trusted-package platform alongside v2. The exhaustive north-star criterion
|
|
(all native capabilities, all authoring affordances and every distribution path) is not yet satisfied.
|
|
|
|
| Stage | Implemented | Remaining scope |
|
|
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
| 1. Existing experience | Zero-source v2 definitions, no empty polling, retained data, request queue, raw repair/export, private/VPN networking, install-to-board | Progressive individual results use v3; the compatible v2 response remains aggregated. |
|
|
| 2. Shared contracts | Versioned client/server SDK, dimensions/scale/theme/locale, typed handlers, native integration adapters, commands, managed storage and advanced views | Extend maintained adapters and primitives across the entire native catalog. |
|
|
| 3. Trusted packages | Portable v3 schema, installations/connections/placements, TSX/CSS modules/assets, immutable artifacts, exact dependency closure, supervised Node, migration/rollback, v2 compatibility and explicit conversion | Native addon build environments and richer package compatibility negotiation. |
|
|
| 4. Creator workspace | Multi-file CodeMirror with local TypeScript service, semantic navigation/rename, retained preview, draft/preview/activate, synthetic scenarios, viewport/scale/theme controls, resizable split, Undo/recovery and Assistant proposals | Visual resource builders, asset upload, project-wide search, and simultaneous viewport comparison. |
|
|
| 5. Native parity | Thirteen reference packages with clean semantic diagnostics; Beszel history/live data, downloads controls, clock/timer, checklist, Sonarr, rack, backup, media and composed views; shared tables and native starters | Complete native-widget coverage and live-service acceptance of every reference behavior. |
|
|
| 6. Workshop lifecycle | Immutable releases, origin tracking, updates/forks, binding preservation, staged activation/rollback, private Workshop, offline archives, portable collections/shared connection setup, inert package browsing | Richer semantic release comparison and catalog presentation. |
|
|
| 7. Application reach | HTTP and richer authentication/TLS, native subscriptions, exact-token webhooks, opt-in retained sampling, URL-free encrypted service connections, local Node file/command access, SQLite/MQTT examples and authenticated companion runner | Maintained SSH/browser adapters and native addon build environments; native binaries need a compatible external runner/service. |
|
|
| 8. Central experience | Board/native customization entrypoints, installed library, Assistant draft editing, MCP lifecycle and external CLI scaffold/build/preview/pack/publish | App/integration suggestions and comprehensive contextual discovery. |
|
|
|
|
## Invariants
|
|
|
|
- Package code and exact dependencies are portable; credentials and connection bindings are local.
|
|
- Saving a draft does not change deployed placements. Activation switches a validated artifact and retains the previous managed rollback unit.
|
|
- Workshop browsing executes no submitted code. V3 execution requires owner trust.
|
|
- Anonymous callers can invoke only explicitly granted named actions with approved inputs on the bound placement.
|
|
- Render through the host React/Mantine runtime. Supervise server code separately for reliability, without claiming sandbox containment.
|
|
- Preserve user state and query identity between compact and advanced views.
|
|
- Keep core runtime independent of Workshop/network availability.
|
|
- Apply schema changes to all three database drivers; document shipped behavior with every stage.
|
|
|
|
## Verification
|
|
|
|
Use focused existing checks and manual acceptance scenarios. Do not add tests or run broad suites/Docker builds without a separate request. Record actual commands and results here as each stage is integrated.
|
|
|
|
## Acceptance reference packages
|
|
|
|
Beszel operations, unified downloads, source-free clock/timer, two-server Sonarr, SVG rack/floor plan, authenticated media wall, API-less backup monitor, household guest controls, persistent checklist, and composed homelab overview.
|
|
|
|
## Workbench and sharing handoff (2026-09-12)
|
|
|
|
Implemented UI: full-page package source workspace; collapsed file rail; tile/advanced/configuration previews;
|
|
static default and reference templates; a local multi-file TypeScript worker; scoped light/dark and scaled viewport
|
|
previews; synthetic scenarios; an accessible resizable source/preview split; offline collection setup; separate draft saving, explicit trust, preview and activation; one document
|
|
Undo/Redo and recovery draft; reusable local connections and meaningful readiness diagnostics; package conversion
|
|
that preserves v2 originals and explicitly replaces selected placements after activation; board placement setup; Workshop release/source review, local binding, staging, fork,
|
|
publish and update controls; supplied compiled artifact/dependency-lock inspection; opt-in history, named guest
|
|
controls and per-placement webhooks; existing Assistant draft read/proposal tools; exact CLI preview page.
|
|
|
|
Assistant proposals compare the visible draft revision, show changed files before/after, require explicit Apply,
|
|
and produce one Undo operation. They do not save, execute or activate source. Local credentials, bindings, preview
|
|
options and response payloads are outside Assistant context. Recognized source credential literals are redacted;
|
|
files containing those redactions cannot be replaced by proposals. Context has a 180,000-character per-response
|
|
source budget; individual larger files and manifests over 60,000 characters require direct editing.
|
|
|
|
The following remain concrete follow-up work, not shipped UI claims:
|
|
|
|
- Editor: automatic import/entrypoint rewrites on file rename, folder organization, binary asset management,
|
|
and project-wide find/replace. Symbol rename and cross-file definitions are implemented.
|
|
- Layout: simultaneous phone/tablet preview comparisons, full board background/geometry emulation, screenshot
|
|
capture and automated visual acceptance. Split resizing, named viewports, scale and local color modes are implemented.
|
|
- Configuration: a visual manifest/options builder and richer schema-driven input forms for guest actions,
|
|
webhooks, and queries. Advanced authors can supply a configuration surface; generic controls and JSON remain.
|
|
- Review: semantic dependency/configuration migration summaries and per-placement readiness reports. Source review
|
|
currently shows whole files before/after. Supplied artifact integrity does not establish source/build equivalence.
|
|
- Operations: an editable collector settings form after creation, richer retained-history charts, visible subscription
|
|
and action tracing, and a library maintenance UI for backend cleanup capabilities. Current history has latest
|
|
samples, a sampled table and technical details; lifecycle activity is inspectable technical data.
|
|
- Workshop: polished screenshot galleries, a richer dependency/license review, release compatibility guidance,
|
|
public package quality signals and public collection catalog presentation. Offline collections are implemented. Browsing must remain inert; never run untrusted previews
|
|
on the Homarr origin merely to make a catalog look interactive.
|
|
- Native customization: expand the template coverage and maintain shared native primitives and versioned SDK
|
|
contracts. A reference fork is an independently editable package, not an automatically synchronized native clone.
|
|
- Assistant: in-editor file/line diagnostics and proposal navigation, smaller contextual reads for huge projects,
|
|
and browser-confirmed visual evidence. Compiled preview-session evidence alone is not a rendering test.
|
|
- Reference breadth: Sonarr operations, local backup reports/fixed commands and authenticated still-image galleries
|
|
now demonstrate real paths. They do not imply arbitrary app adapters, continuous video streaming, lossless media
|
|
delivery, backup restore verification, or exhaustive native-widget feature equivalence.
|
|
|
|
Bounded verification for this UI delivery: 18 existing Assistant contract/pending-action tests passed. Three expanded
|
|
reference packages passed schema validation, client/server compilation and supervised Node preflight. Manual SDK
|
|
smokes covered two-source Sonarr failure isolation and a source-qualified search, camera/Immich image transport,
|
|
backup status/history parsing, preview simulation and a real fixed executable writing only to a temporary file.
|
|
These smokes used local fixtures; live Sonarr/Immich/camera deployments and the new Assistant provider round trip
|
|
still require browser/service acceptance. Record the root's final build/browser status separately.
|
|
|
|
## Integrated verification
|
|
|
|
Verified on `feat/custom-widget-platform` with Node 24.18.0 and pnpm 11.15.1. Commands use `mise exec --` in this workspace.
|
|
|
|
- Next.js production build and Docusaurus production build pass. Next.js is configured to skip its own type validation;
|
|
an independent Next.js `typecheck` passed. The seven affected package typechecks also passed: custom-widgets,
|
|
widget-sdk, db, api, cli, widgets, and workshop.
|
|
- `pnpm check:custom-widgets` passes for 335 production modules. The existing bundle check passes without increasing
|
|
its limit: three routes, largest custom runtime payload 314,085 gzip bytes (1,614,719 raw bytes across 11 chunks).
|
|
The TypeScript worker and declaration assets load locally on authoring routes and are absent from that runtime payload.
|
|
- Focused existing Vitest files pass: custom-api-v2, preview-sessions, backup, and MCP inventory; 37 tests across four
|
|
files. Another 18 existing Assistant contract/pending-action checks passed during implementation. No new test files,
|
|
broad test suite, Docker build or end-to-end suite was added or run.
|
|
- Read-only lint of 256 changed/new production source files exits successfully. Three nonblocking new style warnings
|
|
remain (type-only import, array constructor, variable shadowing), alongside existing framework/PocketBase warnings.
|
|
- Every one of the thirteen reference packages reports zero semantic diagnostics through the actual editor language
|
|
service. Reference browser/server outputs compile and pass supervised worker startup. The real Chromium worker and
|
|
CodeMirror checks cover completion details, semantic diagnostics, F12 cross-file definitions and F2 symbol rename.
|
|
|
|
Production browser acceptance used a separate SQLite database, Redis instance and local server, with no existing user data:
|
|
|
|
- Source-free package preview renders; syntax errors preserve the last successful view and pause its SDK activity.
|
|
- Tile/advanced transitions preserve selection, keyboard controls and focus behavior. The static clock makes one initial
|
|
widget-data load with no periodic data polling through repeated view transitions.
|
|
- The editor split supports pointer and keyboard resizing and persists its preference. Viewport presets, 75% scaling and isolated
|
|
dark mode preserve the preview session. The document remains light while the preview uses dark CSS variables.
|
|
- Mobile source/preview switching preserves the mounted preview. The settled page width matches the 390px viewport;
|
|
deliberately larger widget canvases scroll inside their preview frame.
|
|
- A source package imports through the actual file picker. Its synthetic partial-failure scenario renders a healthy
|
|
memory region beside the simulated storage timeout, labels the scenario and disables live SDK actions.
|
|
- An active package exports as a collection, imports into disabled installations, activates and places successfully on
|
|
the selected board. Retrying reports the existing placement and produces no duplicate. Both original and imported
|
|
widgets render on the board. Collection breadcrumbs display names rather than internal import IDs.
|
|
|
|
Backend/manual acceptance includes immutable archive checks; isolated production CLI/compiler module resolution;
|
|
request queues and cancellation; activation, migration failure and rollback; current/previous artifact retention;
|
|
connection/placement changes racing with activation; stale reviewed-source rejection; exact guest action inputs and
|
|
revocation serialization; fresh native integration permissions; redacted encrypted connection storage; backup key
|
|
rotation and rollback; named webhook validation and revocation that survives rollback; retained history coordination;
|
|
portable collection atomic import/rebinding; and private local Workshop release/fork/update behavior.
|
|
|
|
Adapter checks used real supervised Node execution with local fixtures. They cover two-client download failure and
|
|
control isolation, two-source Sonarr queries, authenticated media transport, fixed backup commands, Node SQLite
|
|
read-only queries, and MQTT authentication/retained messages/publishing/socket cleanup. Synthetic preview checks
|
|
prove server entrypoints are not started, missing fixtures never fall back to real services, delays cancel, old
|
|
sessions keep their original fixture data, and ordinary connected previews still invoke real handlers.
|
|
|
|
SQLite migrations ran against a fresh database. MySQL and PostgreSQL definitions, migration SQL, snapshots and
|
|
identifier lengths were checked, but those database engines were not exercised. No real Beszel/Sonarr/Immich/camera
|
|
or household deployment was available for full service acceptance, and the Assistant provider round trip remains
|
|
unverified. These limits must accompany release acceptance; compilation is not proof of those integrations.
|
|
|
|
The final production build removes all five new runtime-data filesystem tracing warnings. Existing backup/certificate
|
|
tracing warnings and a CommonJS export warning remain. The isolated review server required stopping its old embedded
|
|
WebSocket listener before restart; this was resolved without touching other running applications.
|
|
|
|
## Review fixes
|
|
|
|
The follow-up review found and fixed eight introduced defects:
|
|
|
|
- **P1 — Credential binding during v2 Undo/Redo.** Restoring an earlier source origin, network scope, or authentication
|
|
destination now discards pending credentials belonging to the newer binding. Previously the editor kept credentials
|
|
when the source ID and secret type matched, allowing a preview or save to send them to the wrong service. The editor
|
|
and server now use the same binding comparison; same-origin path edits preserve compatible credentials.
|
|
- **P1 — Existing v2 callback compatibility.** Adding the `host` root also reserved that name for callback parameters.
|
|
Existing `data.hosts.map(host => host.name)` templates failed validation and rendering. Root host context remains
|
|
available, while callbacks keep their existing local-name behavior.
|
|
- **P2 — Cold server startup eviction.** Capacity eviction could stop a newly ready process before an accepted
|
|
invocation registered its pending work. Invocations, subscriptions and preflight now reserve the process across
|
|
asynchronous startup, and eviction checks that reservation before and after waiting.
|
|
- **P2 — Duplicate server processes after eviction.** Two calls for one artifact could each start a server after
|
|
asynchronous idle eviction, replacing the tracked process and leaving the other unsupervised. The supervisor now
|
|
checks for a concurrently started artifact again before allocating a process.
|
|
- **P2 — Partial credential edits.** Changing only a saved Basic Auth password cleared its username; replacing a bearer
|
|
or cookie credential could also remove a TLS private key. The editor now submits only changed credential fields.
|
|
The API merges them with freshly read encrypted credentials inside the existing connection-change lock and rejects
|
|
patches against a different authentication kind. Explicit full replacement remains supported.
|
|
- **P2 — Preview managed storage.** Browser hooks and server handlers previously used separate preview stores. Both
|
|
now use the same authorized temporary backend for user, placement and installation scopes. Successful SDK actions
|
|
also invalidate mounted storage queries so server writes appear in the preview.
|
|
- **P2 — Guest-action revocation.** Invalid JSON in an edited allowed-input field blocked disabling an existing grant.
|
|
Revocation now bypasses input parsing; enabling a grant still requires valid inputs.
|
|
- **P2 — Workshop validation order.** Exceeding the combined retained/new screenshot limit could publish an immutable
|
|
package release before reporting the validation error. The combined count is now validated before publication and
|
|
checked again after refreshing the submission.
|
|
|
|
Review verification: all six affected typechecks pass (widget-sdk, custom-widgets, workshop, api, widgets and Next.js),
|
|
with a final custom-widgets recheck after the process-sharing fix. Focused existing JSX policy, Workshop client/schema
|
|
and custom-api-v2 files pass: **127 tests across four files**. Formatting and focused lint pass; `git diff --check` passes.
|
|
The Custom Widgets architecture check also passes for 335 production modules.
|
|
No repository test files were added during review.
|
|
|
|
Temporary manual reproductions cover both server-capacity races, credential patches, all three preview storage scopes,
|
|
cross-session isolation and discarded-session rejection, Workshop validation ordering, v2 callback rendering, and
|
|
Undo/Redo credential binding. An actual SDK hook mounted in JSDOM confirms that a successful server action refreshes
|
|
displayed managed storage. Chromium checks mounted the actual connection and guest-action editors with fixture API
|
|
responses and verified their submitted payloads. These checks use synthetic credentials and isolated data.
|
|
|
|
The production builds and full application/browser acceptance above predate these review fixes. They were not rerun
|
|
for this focused review; live external services, MySQL/PostgreSQL engines and the Assistant provider round trip remain
|
|
outside the verified coverage.
|