Skip to content

Releases: open-element/openelement

v0.41.0-alpha.6

Choose a tag to compare

@github-actions github-actions released this 06 Jul 23:56

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.6

Highlights

  • App/protocol ownership boundary@openelement/app now 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
    the next dist-tag.

What changed

Architecture & ownership

  • packages/ssg/src/route-scanner.ts: fileToTagName now 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.ts and related entry generators: replaced
    the deprecated isCustomElementName with isValidTagName from
    @openelement/core/tag-utils.
  • Removed the unused packages/ssg/src/custom-element-name.ts surface.

Tooling & release hygiene

  • packages/core/src/write-json.ts: writeJson renamed to formatJson;
    writeJson remains as a deprecated alias.
  • packages/ssg/src/entry-render-helpers.ts: removed the dead varName
    parameter from routeTagNameExpr.
  • tools/lib/process.ts: runWithOutput aligned with runCommand options API.
  • tools/lib/git.ts: gitIsTracked now passes -c core.quotepath=false to
    git ls-files.
  • tools/consumer-smoke.ts: fixed pre-existing result.output reference to
    stdout + stderr after the runWithOutput API 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.md to 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.ts anchor replacements updated so the next release
    cycle starts from 0.41.0-alpha.6.

Verification

Local and CI gates passed before publish:

  • deno task fmt:check, deno task lint, deno task typecheck
  • deno task test — 1221 passed, 0 failed
  • deno task test:coverage:check — 71.1% >= 70%
  • deno task consumer:core-smoke
  • deno task pack:dry-run
  • deno task arch:check, deno task repo:hygiene,
    deno task package-surface:check, deno task graph:check
  • deno 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

Choose a tag to compare

@github-actions github-actions released this 01 Jul 07:12

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/router for 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 www docs/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 dev and main lines 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

Choose a tag to compare

@SisyphusZheng SisyphusZheng released this 25 Jun 10:23

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/ui integration blocked by deno pack JSX transpilation gap;
    compilerOptions.jsx config added in packages/ui/deno.json as 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: added compilerOptions.jsx: "react-jsx" with
    jsxImportSource: "@openelement/core". This tells Deno's TypeScript compiler
    to transform JSX during deno pack — verified that packed output produces
    jsx() calls instead of raw JSX. The actual deno pack transpilation
    pipeline fix is deferred to alpha.5.

Release Tooling

  • tools/autoflow/release.ts: added git pull --rebase origin main before
    each git push origin main to 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/app BuildContext deepening
  • Test harness consolidation (-619 lines)
  • Shared allPackageAliases() in tools/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,
    disposeOpenElement
  • packages/core/__tests__/client-runtime.test.ts (223 lines): edge case coverage
  • examples/open-element-in-fresh/ (10 files): Fresh 2.3+ project with
    vite.config.ts, client.ts, main.ts (App API), routes, islands, components
  • packages/ui/deno.json: compilerOptions.jsx groundwork
  • docs/integrations/open-element-in-fresh.md: integration guide
  • Release tooling: git pull --rebase step 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

  1. @openelement/ui not yet bundled in Fresh example — the npm package ships
    .js files with raw JSX (from deno pack without JSX transform). Inline
    custom element stubs used as ponytail. Full integration requires the
    deno pack transpilation pipeline fix (alpha.5).

  2. npm native binding flake — intermittent Cannot find native binding
    error in CI test suite (pre-existing, unrelated to alpha.4 changes).

  3. 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

Choose a tag to compare

@github-actions github-actions released this 25 Jun 05:20

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 supporton-sl-change, on-md-input etc. route to native CustomEvent listeners. Zero adapter code required.
  • Pure ESM artifact gatespublint --strict + attw --profile esm-only run against all 11 npm tarballs. Custom ESM scans reject require(), CJS globals, and host APIs in browser-facing packages.
  • Architecture deepening — BuildContext enriched with typed registerPlugin, test DOM harness consolidated (-619 lines into test-utils.ts), Vite entry path converged, package alias generation shared via allPackageAliases().
  • Test isolation hardened — All test files use withMockDocument per-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:

  • parseSemver regex extended to accept -alpha.* pre-release suffixes
  • deno pack always uses --allow-dirty (worktree dirtied by deno fmt during bump)
  • npm publish E403 errors skip already-published packages instead of aborting
  • Pre-release versions use plan=minor (not plan=patch which calls broken nextPatchVersion)
  • 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:smoke and package-artifacts:check)
  • E2E: 100 Chromium tests PASS
  • Release: 11/11 packages published to npm with provenance

Release notes

v0.41.0-alpha.2

Choose a tag to compare

@github-actions github-actions released this 25 Jun 02:09

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 splitjsx-render-dom.ts no longer calls effect() directly; it emits BindingDescriptors. All signal lifecycle lives in binding-activation.ts. <Show>/<For> are now first-class conditional/list binding kinds.
  • BindingDescriptor registry — central switch replaced with a Map-based registry. Factory constructors (bindText, bindAttr, bindClass, bindHtml, bindConditional, bindList, etc.) make the API shallower and extensible.
  • Static subpath validatedopen-button imports escapeAttr from @openelement/core/static, proving SSR/SSG consumers can avoid pulling signal/hydration runtime code.
  • Safari adoptedStyleSheets fix — removed unsupported :host-context selectors; added openPropsRootSheet with :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 after dispose()
  • Double-dispose in registerDispose
  • cacheAccess leaking new object per getter call
  • VNodeCacheAccess public export exposing internal state
  • DANGEROUS_KEYS leaking from public barrel
  • bindRender accepting empty lifecycle default
  • --blue-10--teal-10 typo 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

Choose a tag to compare

@github-actions github-actions released this 24 Jun 01:50

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 pack and 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 packnpm 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 call Deno.*.
  • deno task publish:jsr:release — keep JSR as secondary publish path.

Removed / folded surfaces

  • @prop() decorator runtime — keep static props only.
  • ReactiveHost speculative abstraction.
  • packages/core/src/adapter-registry.ts, dsd-collector.ts.
  • packages/signal/src/alien-engine.ts@preact/signals-core is the only supported engine.
  • packages/ssg/src/ssg-pwa.ts speculative PWA generator.
  • packages/adapter-vite/src/devtools/, build-pipeline.ts, optional-package-stubs.ts.
  • packages/ssg/src/route-scanner-ast.ts and packages/content/src/nav/scanner.ts — replaced with glob + regex scanners.
  • packages/ssg/src/entry-descriptor.ts — inlined into entry-renderer.ts.
  • packages/ui/src/manifest.ts — replaced with generated Custom Elements manifest.
  • packages/ui/src/daisy-classes.ts and open-props-tokens.ts — replaced with plain .css files.
  • tools/record-evolution.ts, tools/require-hub-archive-approval.ts.

Architecture changes

  • @openelement/core split into static, hydrate, and csr subpath exports.
  • BindingDescriptor unifies signal-to-DOM binding across CSR and DSD hydration.
  • MemoryIsrCache remains the reference ISR implementation; FileIsrCache removed after audit found no production callers.
  • CSSStyleSheet used natively in style-sheet.ts; minimal SSR shim retained.
  • Logger simplified to tagged factory createLogger(tag).
  • OpenElementError normalized to single options-based constructor.
  • packages/adapter-vite/src/build.ts refactored: SSG post-processing moved to packages/ssg/src/build-postprocess.ts.
  • packages/content/src/index.ts split 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; use static props.
  • ReactiveHost removed.
  • Several single-implementation protocol interfaces removed or relocated into consumers.
  • PWA manifest removed.

Migration

  1. Update lockfiles and import maps to use npm:@openelement/* specifiers.
  2. Replace @prop() decorators with static props declarations.
  3. If you used jsr:@openelement/*, switch to npm:@openelement/*.
  4. Starter apps generated by @openelement/create already emit npm imports.

Verification

  • deno task fmt:check — passed
  • deno task lint — passed
  • deno task typecheck — passed
  • deno task test — passed (935 passed, 0 failed)
  • deno task graph:check — passed (11 packages, consistent DAG)
  • deno task build — passed
  • deno task repo:hygiene — passed
  • deno task autoflow:ci — 21/21 gates PASS
  • deno 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 adoptedStyleSheets theme recompute bug is mitigated by removing token sheets from open-theme-toggle static styles; a fuller fix is tracked for v0.41.0-alpha.2.
  • @openelement/core/static subpath 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

v0.40.7

Choose a tag to compare

@SisyphusZheng SisyphusZheng released this 15 Jun 22:43

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.server setup used by the Playwright E2E suite with a
    Deno static server (www/e2e/static-server.ts) that supports directory
    indexes, .html pretty 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=1 escape 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 both autoflow-ci.yml and
    autoflow-release.yml; the GitHub-hosted runner does not ship with Chromium.
  • Grant --allow-env to all AutoFlow3 task invocations in deno.json so 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 existing deploy:pages
    gate behavior.
  • Update AutoFlow3 release-plan tests to assert the full plan with credentials
    and the trimmed plan without them.
  • Repair consumer-local.ts workspace mappings for @openelement/router and
    @openelement/core/prop so generated starter apps resolve the new core
    ./prop export and the router dependency pulled in by app.
  • Skip smoke-deploy when 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 test pass.
  • deno task graph:check and deno task package-surface:check confirm no
    package or public surface changes.
  • deno task workflow:check and deno task workflow:check-slimming pass.
  • Local deno task autoflow:push passes.
  • GitHub Actions AutoFlow CI passes on dev.

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

Choose a tag to compare

@SisyphusZheng SisyphusZheng released this 15 Jun 12:40

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.md as a persistent architecture
    artifact.
  • Add ADR-0106 documenting the audit-driven cleanup scope and boundaries.
  • Update docs/status/STATUS.md and docs/roadmap/ROADMAP.md for 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.ts from 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.ts from 20 to 58 tests,
    covering all 13 open-* components plus manifest metadata.
  • Add missing open-dropdown, open-modal, and open-tabs declarations to
    packages/ui/src/manifest.ts and update smoke tests accordingly.

Error Handling

  • Introduce formatError(e: unknown): string in packages/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.ts into
    route-scanner-ast.ts + route-scanner-fs.ts + orchestrator
    (~795 → ~555 lines).
  • Split packages/element/src/open-element.ts into
    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.ts into alias-utils.ts and
    build-constants.ts (~526 → ~492 lines).

Runtime Safety

  • Replace shadowRoot! assertions in open-element.ts with a guarded local
    variable.
  • Add runtime guards for RegExp match indices in postprocess.ts.
  • Add runtime guard for openElement.module in entry-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, and ui/src/open-code-block.tsx
    logging through OpenElementLogger.
  • 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 test all pass.
  • deno task type-safety:check reports 0 explicit any.
  • deno task graph:check and deno task package-surface:check confirm no
    package or public surface changes.
  • deno task arch:check, deno task repo:hygiene,
    deno task workflow:check, and deno task workflow:check-slimming pass.
  • deno task docs:check-current, deno task docs:check-public, and
    deno task docs:check-strategy pass.
  • deno task consumer:local and deno task consumer:packaged pass.
  • deno task nitro:proof:node and deno task nitro:proof:workers pass.
  • deno task publish:dry-run passes.

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-run

v0.40.5 (superseded by v0.40.6)

Choose a tag to compare

@SisyphusZheng SisyphusZheng released this 15 Jun 11:57

⚠️ Superseded by v0.40.6. The v0.40.5 JSR publish completed, but the post-publish consumer smoke test failed; v0.40.6 contains the required fixes.

v0.40.4: packaged starter smoke hardening

Choose a tag to compare

@SisyphusZheng SisyphusZheng released this 15 Jun 00:39

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/cors
    • hono/logger
    • hono/request-id
    • hono/secure-headers
  • Added consumer:packaged as 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.js for 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

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.