Releases: open-element/openelement
Release list
v0.41.0-alpha.6
v0.41.0-alpha.6
Release date: 2026-07-06
Previous package line: 0.41.0-alpha.5
Released package line: 0.41.0-alpha.6
npm tag: next
Git tag: v0.41.0-alpha.6
v0.41.0-alpha.6 closes the App/protocol architecture hardening line. It makes
OpenElement App own the core application concepts while keeping Vite, Hono,
Nitro, and Deno Desktop as official adapters and drivers. The release also
closes the front-half cleanup audit, the product-truth ADRs, and the CodeQL /
trust-boundary backlog.
Install
# create a new project
deno run -A npm:@openelement/create@0.41.0-alpha.6 my-app
# or install a specific package
npm install @openelement/core@0.41.0-alpha.6Highlights
- App/protocol ownership boundary —
@openelement/appnow owns
RouteGraph,RenderPipeline,RequestContext,AssetManifest,
IslandManifest,DeploymentTarget, and Deno Desktop target contracts. - Product truth — ADR-0110 adopts the public doctrine
Web Components Fullstack Framework + Basic Element; ADR-0111 records that
official adapters implement OpenElement-owned concepts rather than defining
product identity. - Front-half cleanup audit closure — duplicate implementations, redundant
dependencies/configs, stale resolver maps, leaked router internals, and dead
tooling helpers removed. - Trust-boundary hardening — CodeQL/code-scanning backlog (#186–#191)
closed; generated island dynamic imports use an admitted module-specifier
boundary; shared JavaScript literal escaping is used for generated client and
server entry code. - Reader regression dogfood — the Deno Desktop Reader is promoted from a
working proof to regression-grade evidence for the framework contract. - npm provenance — all 11 packages published to npm with provenance under
thenextdist-tag.
What changed
Architecture & ownership
packages/ssg/src/route-scanner.ts:fileToTagNamenow delegates to
@openelement/core/pathToTagName, so route and island tag-name derivation
share one source of truth and top-level page files produce valid custom
element names.packages/core/src/island-transform.ts: reuses the shared tag-name helper,
normalizing unsafe characters to valid custom element names instead of
throwing.packages/ssg/src/island-manifest.tsand related entry generators: replaced
the deprecatedisCustomElementNamewithisValidTagNamefrom
@openelement/core/tag-utils.- Removed the unused
packages/ssg/src/custom-element-name.tssurface.
Tooling & release hygiene
packages/core/src/write-json.ts:writeJsonrenamed toformatJson;
writeJsonremains as a deprecated alias.packages/ssg/src/entry-render-helpers.ts: removed the deadvarName
parameter fromrouteTagNameExpr.tools/lib/process.ts:runWithOutputaligned withrunCommandoptions API.tools/lib/git.ts:gitIsTrackednow passes-c core.quotepath=falseto
git ls-files.tools/consumer-smoke.ts: fixed pre-existingresult.outputreference to
stdout + stderrafter therunWithOutputAPI change.
Docs & website
- Updated README, README.zh,
docs/status/STATUS.md,docs/roadmap/ROADMAP.md,
docs/current/VERSION_PLAN.md,docs/current/PACKAGE_SURFACE.md, and
docs/governance/PROJECT_WORKFLOW.mdto reflect alpha.6 as the released line
and alpha.7 as the active next line. - Updated www version constant, roadmap page, homepage, getting-started guide,
example comments, and design README. - Added this release note and updated
docs/release/v0.41.0.md.
Release evidence
tools/autoflow/release.tsanchor replacements updated so the next release
cycle starts from0.41.0-alpha.6.
Verification
Local and CI gates passed before publish:
deno task fmt:check,deno task lint,deno task typecheckdeno task test— 1221 passed, 0 faileddeno task test:coverage:check— 71.1% >= 70%deno task consumer:core-smokedeno task pack:dry-rundeno task arch:check,deno task repo:hygiene,
deno task package-surface:check,deno task graph:checkdeno task docs:truth
Post-publish npm consumer smoke passed in the AutoFlow Release workflow.
Migration
No breaking changes from 0.41.0-alpha.5. Update your dependency specifiers:
- "@openelement/core": "npm:@openelement/core@^0.41.0-alpha.5"
+ "@openelement/core": "npm:@openelement/core@^0.41.0-alpha.6"Full changelog
See the alpha.6 plan for detailed scope and acceptance criteria:
docs/release/v0.41.0-alpha.6-plan.md.
AutoFlow3 release evidence: approved-release-v0.41.0-alpha.6-2026-07-06T23-55-21-058Z.
v0.41.0-alpha.5
v0.41.0-alpha.5 - SPA Mode + Deno Desktop Reader Proof
Published: 2026-07-01
Tag: v0.41.0-alpha.5
Package line: 0.41.0-alpha.5 across the 11-package @openelement/* graph
Release type: prerelease
What This Alpha Proves
v0.41.0-alpha.5 proves that OpenElement is no longer only an SSG/SSR-first Web Components framework. The same component model now supports a first-class single-page application mode and a desktop-shaped app proof.
The desktop proof is intentionally local/open and legally clean: it is a WeRead-style Reader practice app backed by fixtures, local PDF/text sources, and public GitHub repo/path sources. It does not use WeRead private APIs, account cookies, scraping, or copyrighted book content.
Highlights
- Added SPA mode through
defineApp({ mode: 'spa' })in@openelement/app. - Added client-side routing primitives in
@openelement/routerfor desktop-style shells. - Expanded the Deno Desktop Reader proof into a product-shaped app with bookshelf, reading surface, progress, notes, search, source ingestion, Markdown export, settings, and Preact island usage.
- Hardened the framework boundary around SPA/desktop workflows while keeping SSG/SSR as the default OpenElement path.
- Refreshed
wwwdocs/API content and visual polish as part of the alpha.5 closure pass. - Verified third-party Web Component SSG behavior and browser-only component safety from the alpha.5 issue train.
- Cleaned up PR/release evidence follow-ups so the
devandmainlines converged cleanly after release.
Published Packages
All current workspace packages are aligned to 0.41.0-alpha.5:
@openelement/adapter-vite@openelement/app@openelement/content@openelement/core@openelement/create@openelement/element@openelement/protocol@openelement/router@openelement/signal@openelement/ssg@openelement/ui
Release Evidence
AutoFlow3 release evidence completed for approved-release-v0.41.0-alpha.5-2026-07-01T07-10-41-230Z.
The release gate covered the project quality and publishing flow, including:
- format, lint, typecheck, graph, package-surface, workflow, repo hygiene, docs, architecture, protocol-boundary, type-safety, Deno API, and text-integrity checks;
- unit/integration tests, coverage gate, build, Playwright E2E, Nitro Node/Workers proofs, local and packaged consumer smoke, core smoke, third-party WC smoke, package artifact checks, pack dry run, Pages deploy, and deploy smoke;
- npm package publishing and post-publish npm consumer smoke;
- tag and GitHub release publication.
Important Follow-Ups
Alpha.5 deliberately stops before wider architecture and product expansion. The follow-up work is now split into explicit issue trains:
- Alpha.6 App/protocol architecture hardening: #145 through #154.
- Alpha.6 CodeQL/static-analysis cleanup: #186 through #191.
- Alpha.6 product truth, ADR, and docs-truth cleanup: #192 through #194.
- Alpha.7 read-only/accountless Mac Mastodon Desktop incubation: #195 through #201, with #57 as the parent PRD.
Non-Goals Preserved
- No WeRead private API integration.
- No copyrighted book fixture dependency.
- No Mastodon/GoToSocial app in alpha.5 or alpha.6.
- No OAuth, direct messages, notifications, or authenticated social mutations in alpha.7.
- No React/Vue/Svelte adapter expansion unless a later route explicitly needs it to prove disposal or interop semantics.
Links
- Alpha.5 implementation PR: #121
- Release tag:
v0.41.0-alpha.5 - Next architecture plan:
docs/release/v0.41.0-alpha.6-plan.md - Next desktop incubation plan:
docs/release/v0.41.0-alpha.7-plan.md
v0.41.0-alpha.4 — Cross-Framework Web Components Integration
v0.41.0-alpha.4 — Cross-Framework Web Components Integration
Summary
Alpha.4 proves the inverse of alpha.3: openElement components can be consumed
inside third-party frameworks. A lightweight client runtime
(@openelement/core/hydrate) enables Preact island hydration in Deno Fresh 2.3+.
Combined with alpha.3's proof of consuming third-party WCs inside openElement,
this completes the cross-framework interop contract in both directions.
New in Alpha.4
Lightweight Client Runtime (@openelement/core/hydrate)
hydrateOpenElement(container)— bootstraps and hydrates openElement custom
elements from any framework that can call a function on DOM ready.disposeOpenElement(scope)— cleanly tears down hydration observers.- Zero Deno runtime dependency; works in any browser/Node ESM environment.
- 191-line core with 223-line test suite covering edge cases.
Fresh 2.3+ Integration Proof
examples/open-element-in-fresh/— canonical Fresh 2.3+ (Vite) project
demonstrating<open-button>and<open-card>custom elements alongside
Preact islands.- OpenElements island registers custom elements inline (ponytail: full
@openelement/uiintegration blocked bydeno packJSX transpilation gap;
compilerOptions.jsxconfig added inpackages/ui/deno.jsonas groundwork). - PreactCounter island proves bilateral interop — Preact signals and openElement
shadow DOM coexist without conflict. - Build verified:
deno task build→ 26 client + 174 SSR modules.
Package Build Fix (groundwork)
packages/ui/deno.json: addedcompilerOptions.jsx: "react-jsx"with
jsxImportSource: "@openelement/core". This tells Deno's TypeScript compiler
to transform JSX duringdeno pack— verified that packed output produces
jsx()calls instead of raw JSX. The actualdeno packtranspilation
pipeline fix is deferred to alpha.5.
Release Tooling
tools/autoflow/release.ts: addedgit pull --rebase origin mainbefore
eachgit push origin mainto prevent push-rejected failures from divergent
remote state.- Fixed step naming in CI release path for clarity.
- Updated release anchor strings to
0.41.0-alpha.4.
Changes Since Alpha.3
Key Differences
| Area | Alpha.3 | Alpha.4 |
|---|---|---|
| Direction | Consume external WCs in openElement | openElement consumed in external frameworks |
| Proof | Lit/Shoelace/MWC smoke test (18 tests) | Fresh 2.3+ Preact islands + inline WCs |
| Runtime | @openelement/app build context |
@openelement/core/hydrate client runtime |
| Packaging | Pure ESM artifact gates (publint + ATTW) | JSX packaging groundwork (compilerOptions.jsx) |
| Shared | allPackageAliases() utility |
Release tooling hardening (pull-before-push) |
Alpha.3 Capabilities (Carried Forward)
- Lit, Shoelace, Material Web Components smoketest passing
@openelement/appBuildContext deepening- Test harness consolidation (-619 lines)
- Shared
allPackageAliases()intools/lib/package-graph.ts - 18 Preact island proof tests (client-runtime.test.ts + preact-smoke.test.ts)
Alpha.4 Additions
@openelement/core/src/client-runtime.ts(207 lines):hydrateOpenElement,
disposeOpenElementpackages/core/__tests__/client-runtime.test.ts(223 lines): edge case coverageexamples/open-element-in-fresh/(10 files): Fresh 2.3+ project with
vite.config.ts,client.ts,main.ts(App API), routes, islands, componentspackages/ui/deno.json:compilerOptions.jsxgroundworkdocs/integrations/open-element-in-fresh.md: integration guide- Release tooling:
git pull --rebasestep added
Bot Review
PR #113 underwent 10 rounds of automated opencode-review across 27 changed files.
All critical bugs, documentation inconsistencies, and code quality issues were
resolved. The final CI (AutoFlow) passed green.
Known Limitations
-
@openelement/uinot yet bundled in Fresh example — the npm package ships
.jsfiles with raw JSX (fromdeno packwithout JSX transform). Inline
custom element stubs used as ponytail. Full integration requires the
deno packtranspilation pipeline fix (alpha.5). -
npm native binding flake — intermittent
Cannot find native binding
error in CI test suite (pre-existing, unrelated to alpha.4 changes). -
Dev/main sync divergence — cherry-pick-based release workflow leaves
different commit hashes on dev vs main. Manual merge-back required after
each release. Alpha.5 may consider merge-based release strategy.
Package Lineup (11 packages)
All at 0.41.0-alpha.4:
@openelement/signal @openelement/protocol @openelement/core
@openelement/element @openelement/ui @openelement/router
@openelement/app @openelement/ssg @openelement/content
@openelement/adapter-vite @openelement/create
v0.41.0-alpha.3
v0.41.0-alpha.3 — Cross-Framework Web Components Integration
Pre-release. Proves that openElement can consume mature third-party Web Components (Lit, Shoelace, Material Web) with zero adapter code, enforces pure ESM quality gates on all npm artifacts, and deepens the architecture with three improvement candidates from the alpha.2 architecture review.
Highlights
- Third-party WC verification — Lit 3.3.3, Shoelace 2.20.1, and Material Web 2.4.1 render, hydrate, and remain interactive inside openElement. Bidirectional nesting verified (openElement in Lit ✅, Lit in openElement ✅).
- Dashed event support —
on-sl-change,on-md-inputetc. route to native CustomEvent listeners. Zero adapter code required. - Pure ESM artifact gates —
publint --strict+attw --profile esm-onlyrun against all 11 npm tarballs. Custom ESM scans rejectrequire(), CJS globals, and host APIs in browser-facing packages. - Architecture deepening — BuildContext enriched with typed
registerPlugin, test DOM harness consolidated (-619 lines intotest-utils.ts), Vite entry path converged, package alias generation shared viaallPackageAliases(). - Test isolation hardened — All test files use
withMockDocumentper-test wrappers. Safe under--shuffle.
Comparison: alpha.2 → alpha.3
| Aspect | alpha.2 | alpha.3 |
|---|---|---|
| Third-party WC | Not validated | Lit/Shoelace/MWM verified end-to-end |
| Custom events | Only standard JSX events | on-sl-change, on-md-input dashed events |
| npm quality gates | None | publint + attw + custom ESM scans |
| Test isolation | 2/3 files wrapped | All test files use withMockDocument |
| BuildContext | Shared mutable bag | Typed registerPlugin + session-like methods |
| Test harness | Duplicated ~1100 lines across 3 files | Consolidated in test-utils.ts (-619 net lines) |
| Vite entry | Docs inconsistent | Converged on @openelement/adapter-vite |
| Consumer-local | Hardcoded aliases | Shared allPackageAliases() in package-graph.ts |
| Bot review | 5 rounds | 4 rounds, all resolved |
Bot review quality impact
Alpha.3 introduced the third-party-wc:smoke and package-artifacts:check gates into autoflow CI. Across 4 review rounds:
- 4 real bugs caught (phase ordering, comment scanner, mock leak, dependency cycle)
- 5 design/API issues (dead wrappers, protocol type mismatch, over-encapsulation, barrel exposure, test isolation)
- 5 code quality items (helper placement, hardcoded anchors, regex edge cases, type-only constraints, limited selector support)
All resolved before merge. PR #110 closed with "Approve as-is."
Regression fixes from alpha.2
Alpha.2 release process exposed several tooling bugs that are now fixed:
parseSemverregex extended to accept-alpha.*pre-release suffixesdeno packalways uses--allow-dirty(worktree dirtied bydeno fmtduring bump)npm publishE403 errors skip already-published packages instead of aborting- Pre-release versions use
plan=minor(notplan=patchwhich calls brokennextPatchVersion) - Cherry-pick-to-main pattern documented for hotfixes that cannot wait for dev→main merge
Verification
- Tests: 244 passed, 0 failed (core), 25 passed (element), 31 passed (app)
- CI: autoflow-ci 25/25 gates PASS (including new
third-party-wc:smokeandpackage-artifacts:check) - E2E: 100 Chromium tests PASS
- Release: 11/11 packages published to npm with provenance
Release notes
v0.41.0-alpha.2
v0.41.0-alpha.2 — Signal-DOM Deepening
Pre-release. Hardens the signal-to-DOM binding seam by extracting HydrationScope into a standalone subpath, splitting the renderer from the activation layer, and replacing the broad BindingDescriptor switch with a registry of factory constructors. All improvements are internal architecture refactors; no public JSX or custom-element API changes.
Highlights
- HydrationScope extracted — hydration lifecycle state (effect disposers, event cleanups, VNode cache) moved to
@openelement/core/hydrate. Third-party runtimes can now hydrate DSD shadow roots without importing@openelement/element. - Renderer / activation split —
jsx-render-dom.tsno longer callseffect()directly; it emitsBindingDescriptors. All signal lifecycle lives inbinding-activation.ts.<Show>/<For>are now first-classconditional/listbinding kinds. - BindingDescriptor registry — central
switchreplaced with aMap-based registry. Factory constructors (bindText,bindAttr,bindClass,bindHtml,bindConditional,bindList, etc.) make the API shallower and extensible. - Static subpath validated —
open-buttonimportsescapeAttrfrom@openelement/core/static, proving SSR/SSG consumers can avoid pulling signal/hydration runtime code. - Safari adoptedStyleSheets fix — removed unsupported
:host-contextselectors; addedopenPropsRootSheetwith:root[data-theme='dark']for document-level theme cascading.
Architecture comparison: alpha.1 → alpha.2
| Aspect | alpha.1 | alpha.2 |
|---|---|---|
| Hydration lifecycle | Inline in OpenElement | Extracted to @openelement/core/hydrate |
jsx-render-dom.ts |
Calls effect() directly |
Pure translator, emits descriptors |
| Show/For effect wiring | Inline in renderer | conditional/list binding kinds |
| BindingDescriptor switch | Central switch with 11 cases |
Map registry + factory constructors |
| cacheAccess API | Lazy getter returning mutable object | Simple setCachedVNode() method |
| Dispose registration | Both Set + AbortSignal (double-dispose risk) | Exclusive: signal OR Set, not both |
reset() after dispose() |
Blocked by #active guard |
Reactivates scope |
| Test mock isolation | Module-level mock, sequential-order dependent | Per-test withMockDocument wrapper, --shuffle safe |
| Bot review gates | None | 5 rounds of opencode-review, 27 findings resolved |
| Release tooling | N/A | Pre-release plan support, --allow-dirty pack |
Bot review quality impact
Alpha.2 introduced opencode-review CI for every PR. Across 5 review rounds, the bot found 27 real issues (11 bugs + 8 encapsulation/API + 8 nits), all resolved before merge. Key catches:
- CSR signal-class binding no-op
reset()dead path afterdispose()- Double-dispose in
registerDispose cacheAccessleaking new object per getter callVNodeCacheAccesspublic export exposing internal stateDANGEROUS_KEYSleaking from public barrelbindRenderaccepting empty lifecycle default--blue-10→--teal-10typo in dark mode tokens
Verification
- Tests: 241 passed, 0 failed (core + element)
- CI: autoflow-ci 21/21 gates PASS
- Consumer builds: local + packaged + core-smoke PASS
- E2E: 100 Chromium tests PASS
- Release: 11/11 packages published to npm with provenance
Release notes
v0.41.0-alpha.1
v0.41.0-alpha.1 — Deno-native npm Distribution & Audit-Driven Slimming
Pre-release. This alpha rewrites openElement's distribution channel from JSR to npm while keeping development Deno-native, and applies a whole-repo over-engineering audit cleanup.
Highlights
- npm-first distribution. All 11
@openelement/*packages are now packed with Deno 2.8+deno packand published to npm with provenance. JSR remains published as a secondary/observation channel but is no longer the primary distribution path. - Audit-driven slimming. ~2,000 net lines removed, 3 runtime dependencies dropped (
alien-signals,esbuild,typescript), and dozens of speculative abstractions folded or deleted. - Restored
@openelement/protocol. After an initial deletion, protocol is back as a minimal type-only contract layer (15 subpath modules, zero runtime code, zero outgoing edges). - Unified signal-DOM activation (ADR-0109 P0/P1).
BindingDescriptor+applyBindingDescriptor()now cover text/attr/class/render/event bindings for both CSR and DSD hydration paths.
Distribution changes
| Before (v0.40.x) | After (v0.41.0-alpha.1) |
|---|---|
| Primary channel: JSR | Primary channel: npm |
deno publish |
deno pack → npm publish --provenance |
Starters import jsr:@openelement/* |
Starters import npm:@openelement/* |
| adapter-vite defaults to JSR source fetching | adapter-vite defaults to npm node_modules resolution (JSR opt-in via registry: 'jsr') |
New tooling
deno task pack— topologically pack all 11 packages.deno task pack:dry-run— CI validation of tarball output.deno task publish:npm— publish to npm with provenance.deno task deno-api:check— enforce that browser-facing packages do not callDeno.*.deno task publish:jsr:release— keep JSR as secondary publish path.
Removed / folded surfaces
@prop()decorator runtime — keepstatic propsonly.ReactiveHostspeculative abstraction.packages/core/src/adapter-registry.ts,dsd-collector.ts.packages/signal/src/alien-engine.ts—@preact/signals-coreis the only supported engine.packages/ssg/src/ssg-pwa.tsspeculative PWA generator.packages/adapter-vite/src/devtools/,build-pipeline.ts,optional-package-stubs.ts.packages/ssg/src/route-scanner-ast.tsandpackages/content/src/nav/scanner.ts— replaced with glob + regex scanners.packages/ssg/src/entry-descriptor.ts— inlined intoentry-renderer.ts.packages/ui/src/manifest.ts— replaced with generated Custom Elements manifest.packages/ui/src/daisy-classes.tsandopen-props-tokens.ts— replaced with plain.cssfiles.tools/record-evolution.ts,tools/require-hub-archive-approval.ts.
Architecture changes
@openelement/coresplit intostatic,hydrate, andcsrsubpath exports.BindingDescriptorunifies signal-to-DOM binding across CSR and DSD hydration.MemoryIsrCacheremains the reference ISR implementation;FileIsrCacheremoved after audit found no production callers.CSSStyleSheetused natively instyle-sheet.ts; minimal SSR shim retained.- Logger simplified to tagged factory
createLogger(tag). OpenElementErrornormalized to single options-based constructor.packages/adapter-vite/src/build.tsrefactored: SSG post-processing moved topackages/ssg/src/build-postprocess.ts.packages/content/src/index.tssplit into focused plugins (blog,nav,sitemap) with an injected fs adapter.
Breaking changes
This is an alpha; the following are intentional breaking changes for retained/removed surfaces:
- Import path migration:
- import { ... } from "jsr:@openelement/core@^0.40.8"; + import { ... } from "npm:@openelement/core@^0.41.0";
@prop()decorator runtime removed; usestatic props.ReactiveHostremoved.- Several single-implementation protocol interfaces removed or relocated into consumers.
- PWA manifest removed.
Migration
- Update lockfiles and import maps to use
npm:@openelement/*specifiers. - Replace
@prop()decorators withstatic propsdeclarations. - If you used
jsr:@openelement/*, switch tonpm:@openelement/*. - Starter apps generated by
@openelement/createalready emit npm imports.
Verification
deno task fmt:check— passeddeno task lint— passeddeno task typecheck— passeddeno task test— passed (935 passed, 0 failed)deno task graph:check— passed (11 packages, consistent DAG)deno task build— passeddeno task repo:hygiene— passeddeno task autoflow:ci— 21/21 gates PASSdeno task autoflow:release --dry-run --approved-plan ADR-0105/v0.40.x-cleanup-train --to 0.41.0-alpha.1— 27/27 gates PASS- Post-publish consumer smoke passed for Node ESM, Deno
npm:, jsDelivr CDN, and Nitro Node/Workers output.
Known issues & follow-up
- Safari
adoptedStyleSheetstheme recompute bug is mitigated by removing token sheets fromopen-theme-togglestatic styles; a fuller fix is tracked for v0.41.0-alpha.2. @openelement/core/staticsubpath export is architecturally sound but needs at least one real static-only consumer before v0.42.- Remaining Medium/Low OpenCode review findings deferred to v0.41.0-alpha.2.
- Deeper signal-DOM unification (merging CSR Path A and hydration Path D) deferred to a focused v0.41.0-alpha.2 workstream.
Full details
- Version plan:
docs/release/v0.41.0-alpha.1-plan.md - ADR-0108 npm distribution notes:
docs/release/v0.41.0.md - Next alpha plan:
docs/release/v0.41.0-alpha.2-plan.md
v0.40.7
v0.40.7 Release Readiness & CI Hardening
Summary
v0.40.7 is a patch release that hardens the v0.40.6 release infrastructure. It
contains no public API or package graph changes. The release closes the gaps
between local release runs and the GitHub Actions CI environment so that the
v0.40.x cleanup train can be published reliably.
Changes
E2E Infrastructure
- Replace the Python
http.serversetup used by the Playwright E2E suite with a
Deno static server (www/e2e/static-server.ts) that supports directory
indexes,.htmlpretty URLs, and SPA fallback for client-side routes. - Raise Playwright test timeout and relax the homepage load-time assertion
outside CI, giving slower local Windows dev boxes room to complete the suite. - Add an
OPEN_ELEMENT_E2E_OFFLINE=1escape hatch in AutoFlow3 policy so local
release runs can skip the Chromium E2E gate when offline or behind slow
networks; CI remains strict.
CI/CD Pipeline
- Add an explicit Playwright browser installation step
(playwright install --with-deps chromium) to bothautoflow-ci.ymland
autoflow-release.yml; the GitHub-hosted runner does not ship with Chromium. - Grant
--allow-envto all AutoFlow3 task invocations indeno.jsonso that
policy-driven environment checks (offline escape hatch, credential gating)
can run.
Release Tooling
- Skip JSR publish, wait-metadata, post-publish smoke, and GitHub release steps
in AutoFlow3 when the required credentials (DENO_AUTH_TOKEN,
GITHUB_TOKEN/GH_TOKEN) are absent, mirroring the existingdeploy:pages
gate behavior. - Update AutoFlow3 release-plan tests to assert the full plan with credentials
and the trimmed plan without them. - Repair
consumer-local.tsworkspace mappings for@openelement/routerand
@openelement/core/propso generated starter apps resolve the new core
./propexport and the router dependency pulled in byapp. - Skip
smoke-deploywhen Cloudflare credentials are absent, allowing local
release runs without CF tokens.
Acceptance
deno task fmt:check,deno task lint,deno task typecheck, and
deno task testpass.deno task graph:checkanddeno task package-surface:checkconfirm no
package or public surface changes.deno task workflow:checkanddeno task workflow:check-slimmingpass.- Local
deno task autoflow:pushpasses. - GitHub Actions
AutoFlow CIpasses ondev.
Verification
- Local E2E can now be served by the Deno static server and has an offline
escape hatch. - CI installs Chromium before running
test:e2e. - Release plan generation is correct both with and without credentials.
v0.40.6 — Audit-Driven Quality Cleanup
v0.40.6 Release Plan
Summary
v0.40.6 closes the internal quality gaps identified by the 2026-06-15
architecture audit (docs/audit/2026-06-15-architecture-audit.md). The release
adds test coverage for element and ui, splits over-large source files,
unifies error handling, cleans up runtime assertions, and removes remaining
ad-hoc console.* usage. No public API or package topology changes are
introduced.
This release also fixes the post-publish consumer smoke failure that affected
v0.40.5: packages/adapter-vite/src/ssg-package-resolver.ts now resolves the
new @openelement/ui subpaths open-dropdown, open-modal, and open-tabs
that were added in the v0.40.6 UI component test hardening. Additionally,
packages/create/deno.json correctly declares its dependency on
@openelement/core/logger, and the JSR publish order places create after
core.
This release is executed under the v0.40.x cleanup-train authority from
ADR-0105 and recorded in ADR-0106.
Changes
Documentation
- Add
docs/audit/2026-06-15-architecture-audit.mdas a persistent architecture
artifact. - Add ADR-0106 documenting the audit-driven cleanup scope and boundaries.
- Update
docs/status/STATUS.mdanddocs/roadmap/ROADMAP.mdfor the v0.40.6
line. - Archive the v0.40.4 plan to
docs/release/v0.40.4-plan.md.
Tests
- Expand
packages/element/__tests__/open-element.test.tsfrom 2 to 22 tests,
covering lifecycle, DSD/CSR, signal hydration, events, static props, error
boundaries, form internals, and params. - Expand
packages/ui/__tests__/components.test.tsfrom 20 to 58 tests,
covering all 13open-*components plus manifest metadata. - Add missing
open-dropdown,open-modal, andopen-tabsdeclarations to
packages/ui/src/manifest.tsand update smoke tests accordingly.
Error Handling
- Introduce
formatError(e: unknown): stringinpackages/core/src/errors.ts. - Replace all
e instanceof Error ? e.message : String(e)patterns across
packages with the shared helper.
File Size Reduction
- Split
packages/ssg/src/route-scanner.tsinto
route-scanner-ast.ts+route-scanner-fs.ts+ orchestrator
(~795 → ~555 lines). - Split
packages/element/src/open-element.tsinto
open-element-render.ts+open-element-hydration.ts+ base class
(~719 → ~602 lines). - Extract alias normalization and build constants from
packages/adapter-vite/src/cli/build-ssg.tsintoalias-utils.tsand
build-constants.ts(~526 → ~492 lines).
Runtime Safety
- Replace
shadowRoot!assertions inopen-element.tswith a guarded local
variable. - Add runtime guards for RegExp match indices in
postprocess.ts. - Add runtime guard for
openElement.moduleinentry-descriptor.ts.
Adapter-Vite Cleanup
- Move alias normalization to
alias-utils.ts. - Move build constants (
DEFAULT_ADAPTER_VERSION_FALLBACK,
SSR_CHUNK_SIZE_WARNING_LIMIT_KB,SANITIZE_HTML_SPECIFIER) to
build-constants.ts.
Logging Cleanup
- Route
router/src/client-router.ts,adapter-vite/src/cli/build.ts,
create/cli.ts,ui/src/open-layout.tsx, andui/src/open-code-block.tsx
logging throughOpenElementLogger. - Leave generated runtime code and the low-level signal engine console logger
unchanged by design.
Acceptance
deno task fmt:check,deno task lint,deno task typecheck, and
deno task testall pass.deno task type-safety:checkreports 0 explicitany.deno task graph:checkanddeno task package-surface:checkconfirm no
package or public surface changes.deno task arch:check,deno task repo:hygiene,
deno task workflow:check, anddeno task workflow:check-slimmingpass.deno task docs:check-current,deno task docs:check-public, and
deno task docs:check-strategypass.deno task consumer:localanddeno task consumer:packagedpass.deno task nitro:proof:nodeanddeno task nitro:proof:workerspass.deno task publish:dry-runpasses.
Verification
deno task fmt:check
deno task lint
deno task typecheck
deno task test
deno task test:coverage:check
deno task build
deno task graph:check
deno task arch:check
deno task repo:hygiene
deno task workflow:check
deno task workflow:check-slimming
deno task docs:check-public
deno task docs:check-current
deno task docs:check-strategy
deno task package-surface:check
deno task signals:check-protocol-boundary
deno task type-safety:check
deno task autoflow:test
deno task autoflow:push
deno task autoflow:ci
deno task nitro:proof:node
deno task nitro:proof:workers
deno task consumer:local
deno task consumer:packaged
deno task publish:dry-runv0.40.5 (superseded by v0.40.6)
v0.40.4: packaged starter smoke hardening
Summary
v0.40.4 closes the packaged-starter smoke gap found after v0.40.3. The release keeps the v0.40.0 product-line cleanup intact and adds a pre-publish AutoFlow3 gate that exercises the generated starter before immutable package publish.
What changed
- Fixed the generated starter import map by replacing the invalid
hono/prefix mapping with explicit Hono subpath mappings:hono/corshono/loggerhono/request-idhono/secure-headers
- Added
consumer:packagedas an AutoFlow3-managed gate for push, CI, and release tiers. - Strengthened packaged starter smoke so it now:
- builds the generated starter locally,
- scans
dist/server/entry.jsfor bare imports, - checks generated import-map coverage,
- runs real Deno resolution with
deno info --config <generated deno.json> dist/server/entry.js.
- Recorded v0.40.3 as the intentionally superseded failed-smoke patch; JSR versions are immutable, so the fix ships as v0.40.4.
Why this matters
The v0.40.3 publish exposed that import-map key coverage alone was insufficient. The generated starter could include a key that exists but still maps to an invalid npm specifier. v0.40.4 moves that failure mode into the pre-publish AutoFlow path, so this class of starter/package resolution issue is caught before publish closure.
Verification
- Dev AutoFlow CI passed: https://github.com/open-element/openelement/actions/runs/27517039156
- Main AutoFlow CI passed: https://github.com/open-element/openelement/actions/runs/27517127731
- Main Publish to JSR passed, including post-publish consumer smoke: https://github.com/open-element/openelement/actions/runs/27517127724
- CodeQL passed on main: https://github.com/open-element/openelement/actions/runs/27517127721
- Code Quality passed on main: https://github.com/open-element/openelement/actions/runs/27517127276
- Local JSR truth check passed for all 11 packages at
0.40.4viadeno info --no-config.
Packages verified
@openelement/core, @openelement/element, @openelement/ui, @openelement/app, @openelement/create, @openelement/protocol, @openelement/adapter-vite, @openelement/signal, @openelement/router, @openelement/content, @openelement/ssg.