* Improve cohost polyfill
* Apply suggestions from code review
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Move <target/> part of the polyfill to targets file.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Improve cohost polyfill
* Apply suggestions from code review
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Move <target/> part of the polyfill to targets file.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Improve cohost polyfill
* Apply suggestions from code review
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Move <target/> part of the polyfill to targets file.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
* Added tests
* Cleaned up
* Updated command
* Fixes based on comments
* Split tests
* Updated helpers
* Fixed constant helper after merge
* Use correct helper
* Added constant for element search
* Added ui helper for element backoffice search
* Added tests for element backoffice search
* Updated tests for finding element by name
* Apply suggestion from @andr317c
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
* Cleaned up
* Reverted npm command
* Fixed npm command
---------
Co-authored-by: Andreas Zerbst <andr317c@live.dk>
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
* Backoffice: Strip inherited class comments from TypeDoc API docs
TypeDoc copies the nearest documented ancestor's class comment onto every
undocumented subclass, which meant every UmbLitElement descendant on
apidocs.umbraco.com showed "The base class for all Umbraco LitElement
elements." as its own description. This plugin clears class-level
comments whose sourcePath doesn't match the reflection's own file, so
classes with no JSDoc render blank instead of borrowing the base's text.
Inherited member comments (methods, properties) are left alone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Backoffice: Address review comments on TypeDoc strip-inherited plugin
Drop the misleading "strip trailing line/column" sentence — nothing actually
strips, and a future TypeDoc release that appends positions to sourcePath
would now self-document its breakage instead of being hidden by a comment.
Document the sources[0]-only limitation around declaration merging in the
docblock so the constraint is visible to future maintainers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* Clear user and user group start nodes when deleting an element container.
* Assert user start node references cleared after container delete
Mirrors the post-delete assertion already present in the user group
sibling test so both tests confirm the reference was cleaned up, not
just that no FK exception was thrown.
* Guard against null entity in PersistDeletedItem override
Mirrors the ArgumentNullException guard in the base
EntityContainerRepository.PersistDeletedItem so a null argument throws
the same exception type.
* perf(core): parallelize independent boot API requests
UmbServerConnection.connect() awaited server status and configuration
sequentially even though they are independent reads; run them with
Promise.allSettled so both errors surface (the app cannot function
without either) while saving a round-trip.
During app startup, public (login) extension registration was awaited
before the auth flow; kick it off in parallel and await it only before
routing, where the login screen actually needs it.
Each serialized call costs a full management-API round-trip, which is
negligible locally but ~150 ms each on high-latency (e.g. Cloud) hosts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(core): only mark connection connected once both calls succeed
Move isConnected.setValue(true) out of #setStatus() into connect() after
the allSettled check, so the observable never reflects a partially
established connection when configuration fails but status succeeded.
Addresses review feedback on the parallelized connect().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: removes @hey-api/openapi-ts from the login project
this is an ongoing project to be able to finally merge 'login' into 'client'
* docs(login): update CLAUDE.md to reflect removal of @hey-api/openapi-ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Entity refs render readonly when their workspace URL can't be resolved.
Also fixes name on remove dialog.
* Apply read-only on the picked content ref only in the non-routable link picker
* Address PR feedback: simplify document item resolver guard in the link picker, document the implicit uui-card-media disabled dependency in input-media, and cover the disabled card state with a test.
* Drop out of date comments.
* Simplify updates.
---------
Co-authored-by: leekelleher <leekelleher@gmail.com>
* Render $index in block detail overlay label.
* Cache $index, resolve append sentinel, and cover with unit tests.
* refactor(block): use pipeline for index deduplication and clean up stale observer
* Rename function to remove the unnecessary umb prefix.
---------
Co-authored-by: leekelleher <leekelleher@gmail.com>
* Show the edit permissions for document type button only for users with settings access.
* Fix translation for message (the "Permissions" tab is not called "Structure").
* Addressed code review feedback.
* Suppress CS0618 obsolete API warnings in Umbraco.Examine.Lucene
Each obsolete API in this project cannot be migrated to its
non-obsolete replacement without either a breaking public API
change or a change in runtime behaviour:
- LuceneIndex.CommitCount: obsolete with no replacement; retained
in diagnostics metadata to preserve existing output
- IHostingEnvironment.MapPathContentRoot: the IHostEnvironment
extension replacement resolves a different environment
abstraction
- FileSystemDirectoryFactory base constructor: the non-obsolete
overload alters Lucene directory configuration behaviour
Each warning is suppressed locally with an explanatory comment
rather than changed, preserving existing behaviour.
Fixes#15015
* Tightened up comments. Added obsoletion version on unversioned attributes.
Removed warning supressions and fixed constructors.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
`core/manifests.ts` already imports and spreads `core/search/manifests.ts`
into its aggregate (line 23 + 58), so importing `searchManifests`
separately in `.storybook/preview.js` and spreading it next to
`coreManifests` registered the same manifests twice. Remove the redundant
import and spread.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #22957 deleted every package's `manifests.ts` and consolidated the
exports into `umbraco-package.ts`, but `.storybook/preview.js` still
imported from the old paths. The result was a Vite resolve error during
`npm run build-storybook` (first failure: "Could not resolve
../src/packages/block/manifests from .storybook/preview.js").
37 import paths swapped from `…/<pkg>/manifests` to
`…/<pkg>/umbraco-package`. The two packages that still expose their
manifests via a standalone `manifests.ts` — `core` and `core/search` —
are left untouched.
Verified by `npm run build-storybook` — succeeds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #22995 added `input-tiptap.stories.ts` with an import from
`'../../manifests.js'`, but PR #22957 (already on release/17.5.0) had
deleted that file and moved the `manifests` array into
`umbraco-package.ts`. The merge into release/17.5.0 didn't catch the dead
import, so Storybook 404s on the story load.
Point the import at the new home — `manifests` is still exported by name,
so this is a one-line path fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`core/manifests.ts` already imports and spreads `core/search/manifests.ts`
into its aggregate (line 23 + 58), so importing `searchManifests`
separately in `.storybook/preview.js` and spreading it next to
`coreManifests` registered the same manifests twice. Remove the redundant
import and spread.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #22957 deleted every package's `manifests.ts` and consolidated the
exports into `umbraco-package.ts`, but `.storybook/preview.js` still
imported from the old paths. The result was a Vite resolve error during
`npm run build-storybook` (first failure: "Could not resolve
../src/packages/block/manifests from .storybook/preview.js").
37 import paths swapped from `…/<pkg>/manifests` to
`…/<pkg>/umbraco-package`. The two packages that still expose their
manifests via a standalone `manifests.ts` — `core` and `core/search` —
are left untouched.
Verified by `npm run build-storybook` — succeeds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #22995 added `input-tiptap.stories.ts` with an import from
`'../../manifests.js'`, but PR #22957 (already on release/17.5.0) had
deleted that file and moved the `manifests` array into
`umbraco-package.ts`. The merge into release/17.5.0 didn't catch the dead
import, so Storybook 404s on the story load.
Point the import at the new home — `manifests` is still exported by name,
so this is a one-line path fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Load enabled extensions in parallel and inline manifest APIs
Replace the for…of/await loop in umb-input-tiptap's #loadExtensions with
Promise.all over .map, so all enabled Tiptap extension APIs are fetched
in parallel. Configured-extension order in _extensions is preserved.
Inline the first-party Tiptap manifest API references: every
`api: () => import('./X.tiptap-api.js')` and the equivalent toolbar /
statusbar / kind references now use a static top-of-file import and
`api: ClassName`. The dynamic `await import('rich-text-essentials.tiptap-api.js')`
fallback in input-tiptap.element.ts is inlined for the same reason.
External (plugin-supplied) Tiptap extensions and the lazy modal/toolbar
UI element imports are unchanged.
Why: on Umbraco Cloud, opening a document workspace with a rich text
editor takes ~16 s uncached, of which ~14.6 s is a single serial
waterfall — 31 extension APIs fetched one after the other from a
for…of await loop, ~170 ms RTT stacked. Replacing the loop with
Promise.all collapses that to roughly one round-trip; eagerly bundling
the first-party manifests removes the dynamic chunk explosion that made
the waterfall so long in the first place. The toolbar APIs (~20 of them)
already load in a sub-100 ms parallel burst against the same server,
confirming HTTP/2 multiplexing handles bulk parallel requests fine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Inline element references for toolbar/statusbar/modal/clipboard manifests
Extends the manifest-inlining pass to the remaining `element: () => import(...)`
and runtime API loader sites in the Tiptap package — toolbar/menu/action-button
kinds, the table & character-map & anchor modals, the colour-picker button, the
property-editor configuration UIs, both clipboard translators, the style-menu
kind, and the default toolbar API fallback in tiptap-toolbar.element.ts.
Result on the same Cloud test site (uncached, 17.5-rc):
Tiptap chunk count: 71 → 4
Total tiptap bytes: ~3.2 MB → ~3.1 MB (essentially unchanged)
Phase 5 of the load — the serial extension chain — collapses to a single
consolidated chunk fetch.
`input-tiptap.element.ts` and `property-editor-ui-tiptap.element.ts` are
intentionally not inlined into anything else: `<umb-input-tiptap>` is a public
element usable standalone (custom dashboards, workspace views), and the
property-editor shell loads via the property-editor UI loader. They remain
exported as their own modules.
CLAUDE.md updated to document the new convention for first-party Tiptap
extensions (direct class refs) and the carve-out for external plugin
extensions that may keep `() => import(...)` to ship their API code in a
separate chunk.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Move extension APIs and elements into a shared lazy boundary chunk
The previous PR collapsed ~70 Tiptap chunks into 3 by inlining first-party API
and element references directly into manifest files. That win came with a real
downside flagged in code review (lke / mra): the API/element implementation
bytes ended up in the manifest registration bundle, so every workspace —
including ones without an RTE — paid ~700 KB of Tiptap code on boot.
This commit keeps the chunk-coalescing win but restores the lazy boundary by
routing every first-party manifest's `api` / `element` reference through a
single shared bundle file `extensions/extension-apis.bundle.ts`. Each manifest
holds a dynamic-import thunk pointing at that one bundle, so:
- Rollup still emits a single chunk for all Tiptap extension code (no chunk
explosion).
- The manifest registration bundle stays slim — it carries only metadata
(alias / label / icon / group / kind / forExtensions) plus the thunks.
- The bundle is only fetched the first time `<umb-input-tiptap>` actually
mounts.
Data-type configuration UIs (`extensions-configuration`,
`toolbar-configuration`, `statusbar-configuration`) read manifest metadata
via `umbExtensionsRegistry.byType(...)` only — they never call
`loadManifestApi` / `loadManifestElement`, so the data-type editor continues
to work without loading any Tiptap implementation code.
Property-editor UI elements (`tiptap-rte`, the three configuration UIs) also
revert to `() => import('./X.element.js')` so each loads on demand from its
own chunk rather than being inlined into the manifest bundle.
`umb-input-tiptap` no longer statically imports the Rich Text Essentials API;
it prepends the alias to the observed list instead, so essentials resolves
through the same lazy bundle as every other extension.
Added a test and stories file that mount `<umb-input-tiptap>` standalone (no
property-editor wrapper) to make the public usage pattern explicit.
Built and verified via `npm run build:for:cms`:
- `dist-cms/packages/tiptap/manifests.js` 48 KB (eager at boot)
- `dist-cms/packages/tiptap/extension-apis.bundle-*.js` 84 KB (lazy)
- `dist-cms/packages/tiptap/tiptap-toolbar-element-api-base-*.js` 654 KB
(lazy dependency of the bundle)
- per-element property-editor UI chunks load on demand when settings open
`npm run check:circular`, `npm run compile`, `npx wtr src/packages/tiptap`
all pass.
Related to #21152, builds on #22995.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Don't mount <umb-input-tiptap> in the standalone test
Mounting the element via fixture() spins up an UmbTiptapRteContext that
consumes UMB_SERVER_CONTEXT. In the unit-test runtime no server context
provider exists, so the context request stays pending. When @open-wc's
fixture tears down at end-of-file the request rejects with
"host disconnected" — surfaced as an unhandled promise rejection that
web-test-runner counts as a fatal runner error, exiting 1 even though every
individual test passed. The rejection happened to be in flight while a
block-grid clipboard test was active in CI, which is why the failure surfaced
there rather than in the tiptap test file itself.
Drop the manifest-registration assertion too — pulling the package-level
`manifests.ts` aggregator triggers a transitive 404 on the
`@umbraco-cms/backoffice/tiptap` importmap entry in the wtr environment.
The class-export + custom-element-registration checks are enough to prove
standalone exportability. The Storybook stories still cover the visual
end-to-end load path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Display variant node name on sort children dialog.
* Preserve user sort order when patching variant names on culture change
Patch names in-place on the existing _tableItems rather than rebuilding
from _children, so a user's drag-sorted or column-ordered arrangement is
not silently reverted if the app culture changes while the modal is open.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Refactor to reduce cyclomatic complexity of #resolveName method.
* Resolve sort dialog variant names and icons via item data resolvers
Replace the inlined variant-name logic in the content sort dialog with the
shared UmbItemDataResolver abstraction, and add UmbMediaItemDataResolver so
media items resolve their active-culture name and icon the same way documents
do. Each content sort entity action now supplies its resolver through manifest
meta, flowing into the modal via a new content-specific modal data type and a
base-action _getModalData() hook. This also removes the previously hard-coded
document icon in the dialog.
* Disable load more when page of items is being retrieved.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: leekelleher <leekelleher@gmail.com>
* Fix migration of embedded block data when blocks are direct siblings in the 13 RTE source code.
* Apply suggestions from code review to update comments.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address review: keep RteBlockHelper in original namespace; tidy docs and comment
- Move RteBlockHelper back to Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_0_0.LocalLinks
to avoid a binary breaking change within the obsolete window (scheduled removal in v18).
Kept as its own file rather than reverting it into LocalLinkRteProcessor.cs.
- Add a <remarks> note on ConvertBlockUdisToKeys explaining that blocks with malformed UDIs
are dropped rather than preserved.
- Replace the opaque "fix recursive hiccup" comment in LocalLinkRteProcessor with one that
describes what the line actually does.
- Move RteBlockHelperTests back to mirror the production namespace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix migration of embedded block data when blocks are direct siblings in the 13 RTE source code.
* Apply suggestions from code review to update comments.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address review: keep RteBlockHelper in original namespace; tidy docs and comment
- Move RteBlockHelper back to Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_0_0.LocalLinks
to avoid a binary breaking change within the obsolete window (scheduled removal in v18).
Kept as its own file rather than reverting it into LocalLinkRteProcessor.cs.
- Add a <remarks> note on ConvertBlockUdisToKeys explaining that blocks with malformed UDIs
are dropped rather than preserved.
- Replace the opaque "fix recursive hiccup" comment in LocalLinkRteProcessor with one that
describes what the line actually does.
- Move RteBlockHelperTests back to mirror the production namespace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Batch WHERE IN queries to avoid SQL Server 2100-parameter limit and add memory files.
* Drop past-incident references from SQL parameter-limit docs
The memory files should describe the current rule and safe patterns;
specific historical bugs belong in commit history, not CLAUDE.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update comments from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Addressed memory file feedback.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Tiptap: Load enabled extensions in parallel and inline manifest APIs
Replace the for…of/await loop in umb-input-tiptap's #loadExtensions with
Promise.all over .map, so all enabled Tiptap extension APIs are fetched
in parallel. Configured-extension order in _extensions is preserved.
Inline the first-party Tiptap manifest API references: every
`api: () => import('./X.tiptap-api.js')` and the equivalent toolbar /
statusbar / kind references now use a static top-of-file import and
`api: ClassName`. The dynamic `await import('rich-text-essentials.tiptap-api.js')`
fallback in input-tiptap.element.ts is inlined for the same reason.
External (plugin-supplied) Tiptap extensions and the lazy modal/toolbar
UI element imports are unchanged.
Why: on Umbraco Cloud, opening a document workspace with a rich text
editor takes ~16 s uncached, of which ~14.6 s is a single serial
waterfall — 31 extension APIs fetched one after the other from a
for…of await loop, ~170 ms RTT stacked. Replacing the loop with
Promise.all collapses that to roughly one round-trip; eagerly bundling
the first-party manifests removes the dynamic chunk explosion that made
the waterfall so long in the first place. The toolbar APIs (~20 of them)
already load in a sub-100 ms parallel burst against the same server,
confirming HTTP/2 multiplexing handles bulk parallel requests fine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Inline element references for toolbar/statusbar/modal/clipboard manifests
Extends the manifest-inlining pass to the remaining `element: () => import(...)`
and runtime API loader sites in the Tiptap package — toolbar/menu/action-button
kinds, the table & character-map & anchor modals, the colour-picker button, the
property-editor configuration UIs, both clipboard translators, the style-menu
kind, and the default toolbar API fallback in tiptap-toolbar.element.ts.
Result on the same Cloud test site (uncached, 17.5-rc):
Tiptap chunk count: 71 → 4
Total tiptap bytes: ~3.2 MB → ~3.1 MB (essentially unchanged)
Phase 5 of the load — the serial extension chain — collapses to a single
consolidated chunk fetch.
`input-tiptap.element.ts` and `property-editor-ui-tiptap.element.ts` are
intentionally not inlined into anything else: `<umb-input-tiptap>` is a public
element usable standalone (custom dashboards, workspace views), and the
property-editor shell loads via the property-editor UI loader. They remain
exported as their own modules.
CLAUDE.md updated to document the new convention for first-party Tiptap
extensions (direct class refs) and the carve-out for external plugin
extensions that may keep `() => import(...)` to ship their API code in a
separate chunk.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Move extension APIs and elements into a shared lazy boundary chunk
The previous PR collapsed ~70 Tiptap chunks into 3 by inlining first-party API
and element references directly into manifest files. That win came with a real
downside flagged in code review (lke / mra): the API/element implementation
bytes ended up in the manifest registration bundle, so every workspace —
including ones without an RTE — paid ~700 KB of Tiptap code on boot.
This commit keeps the chunk-coalescing win but restores the lazy boundary by
routing every first-party manifest's `api` / `element` reference through a
single shared bundle file `extensions/extension-apis.bundle.ts`. Each manifest
holds a dynamic-import thunk pointing at that one bundle, so:
- Rollup still emits a single chunk for all Tiptap extension code (no chunk
explosion).
- The manifest registration bundle stays slim — it carries only metadata
(alias / label / icon / group / kind / forExtensions) plus the thunks.
- The bundle is only fetched the first time `<umb-input-tiptap>` actually
mounts.
Data-type configuration UIs (`extensions-configuration`,
`toolbar-configuration`, `statusbar-configuration`) read manifest metadata
via `umbExtensionsRegistry.byType(...)` only — they never call
`loadManifestApi` / `loadManifestElement`, so the data-type editor continues
to work without loading any Tiptap implementation code.
Property-editor UI elements (`tiptap-rte`, the three configuration UIs) also
revert to `() => import('./X.element.js')` so each loads on demand from its
own chunk rather than being inlined into the manifest bundle.
`umb-input-tiptap` no longer statically imports the Rich Text Essentials API;
it prepends the alias to the observed list instead, so essentials resolves
through the same lazy bundle as every other extension.
Added a test and stories file that mount `<umb-input-tiptap>` standalone (no
property-editor wrapper) to make the public usage pattern explicit.
Built and verified via `npm run build:for:cms`:
- `dist-cms/packages/tiptap/manifests.js` 48 KB (eager at boot)
- `dist-cms/packages/tiptap/extension-apis.bundle-*.js` 84 KB (lazy)
- `dist-cms/packages/tiptap/tiptap-toolbar-element-api-base-*.js` 654 KB
(lazy dependency of the bundle)
- per-element property-editor UI chunks load on demand when settings open
`npm run check:circular`, `npm run compile`, `npx wtr src/packages/tiptap`
all pass.
Related to #21152, builds on #22995.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Tiptap: Don't mount <umb-input-tiptap> in the standalone test
Mounting the element via fixture() spins up an UmbTiptapRteContext that
consumes UMB_SERVER_CONTEXT. In the unit-test runtime no server context
provider exists, so the context request stays pending. When @open-wc's
fixture tears down at end-of-file the request rejects with
"host disconnected" — surfaced as an unhandled promise rejection that
web-test-runner counts as a fatal runner error, exiting 1 even though every
individual test passed. The rejection happened to be in flight while a
block-grid clipboard test was active in CI, which is why the failure surfaced
there rather than in the tiptap test file itself.
Drop the manifest-registration assertion too — pulling the package-level
`manifests.ts` aggregator triggers a transitive 404 on the
`@umbraco-cms/backoffice/tiptap` importmap entry in the wtr environment.
The class-export + custom-element-registration checks are enough to prove
standalone exportability. The Storybook stories still cover the visual
end-to-end load path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Use direct imports in core manifests
* Extract theme aliases into constants file
---------
Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>