Skip to content

Merged TryGhost/Koenig into the Ghost monorepo - #29171

Merged
kevinansfield merged 5198 commits into
mainfrom
koenig-monorepo-merge
Jul 8, 2026
Merged

Merged TryGhost/Koenig into the Ghost monorepo#29171
kevinansfield merged 5198 commits into
mainfrom
koenig-monorepo-merge

Conversation

@kevinansfield

Copy link
Copy Markdown
Member

Implements the plan in #29156: moves all 13 Koenig packages from TryGhost/Koenig into this monorepo under koenig/*, with full git history.

⚠️ Landing instructions — do not squash

This branch must land as a true merge commit (or admin push). Squashing would flatten the ~5,200 imported commits into one and destroy git log / git blame / git bisect for all Koenig code. The branch is structured as:

  • fb6b427a6 — the history import: a single --allow-unrelated-histories merge of the rewritten Koenig history (packages/*koenig/* via git filter-repo, issue refs qualified as TryGhost/Koenig#N)
  • 8 linear integration commits on top (workspace wiring, CI/publishing, packaging, docker dev, docs)

Koenig is frozen at 84bff4510, which is the imported tip — no divergence.

What changes

Workspace integration

  • koenig/* added to the pnpm workspace; all Ghost consumers (ghost/core, ghost/admin, apps/*) now use workspace:* for kg packages and koenig-lexical — nothing in dev or CI installs Koenig from npm
  • Koenig inter-package deps use workspace:~ so publish rewrites them to ~x.y.z (npm stays the patch-version source of truth)
  • Scripts converted yarn → pnpm; test:e2e renamed test:acceptance; phantom deps exposed by pnpm strict linking added explicitly

Publishing (release-tag lane only)

  • New publish_koenig_packages job runs after publish_ghost on v* tags: per-package git-diff vs the previous release tag, next-patch version computed from npm, OIDC publish in topological order (.github/scripts/publish-koenig-packages.js)
  • workflow_dispatch escape hatch for one-off publishes (publish-koenig-package.yml)
  • npm packages remain published for external consumers only

Release packaging

  • ghost/core/scripts/pack.js bundles kg packages as component tarballs inside the Ghost archive, pinned via pnpm overrides — production installs can never resolve Koenig from the registry, so no version-skew window

CI

  • core path filters cover koenig/** (editor-UI packages excluded); Playwright matrix selection is now tag-based (--projects 'tag:playwright') instead of directory-based
  • Koenig demo deploys to koenig.ghost.org from main pushes touching koenig/**

Dev workflow

  • Docker dev mounts the 10 server-side kg packages; pnpm dev:lexical now runs the in-repo editor watcher + preview server (no external checkout needed)

Verification

  • 29-project nx build; 12 koenig projects test:unit + lint green
  • koenig-lexical Playwright: 760 passed / 27 skipped; kg-unsplash-selector: 4 passed
  • ghost/core unit 7180/7180; ghost-admin ember 1066/1066
  • Release archive verified end-to-end: packed, extracted, CI=true pnpm install --prod resolves all kg packages from file:components/*.tgz, require('@tryghost/kg-html-to-lexical') works
  • Publish script dry-run computes correct next versions for all 13 packages
  • Docker dev boots with kg packages loading in-container; pnpm dev:lexical rebuild loop verified through the gateway

Org-side follow-ups (before/at landing)

  • npm trusted publishing (OIDC) for all 13 packages → TryGhost/Ghost workflows
  • Enable GitHub Pages (gh-pages branch) on this repo + copy TENOR_API_KEY / KLIPY_API_KEY secrets for the demo deploy
  • Decide whether to rewire Sentry sourcemap upload (old IS_SHIPPING flow) into the publish job — deliberately dropped for now
  • Archive TryGhost/Koenig after landing

9larsons and others added 30 commits March 20, 2026 15:51
no ref

The typescript migration requires this change to not throw errors on lint locally while building.
 - @tryghost/html-to-mobiledoc@3.2.22
 - @tryghost/kg-card-factory@5.1.13
 - @tryghost/kg-clean-basic-html@4.2.21
 - @tryghost/kg-converters@1.1.20
 - @tryghost/kg-default-atoms@5.1.8
 - @tryghost/kg-default-cards@10.2.11
 - @tryghost/kg-default-nodes@2.0.16
 - @tryghost/kg-default-transforms@1.2.39
 - @tryghost/kg-html-to-lexical@1.2.39
 - @tryghost/kg-lexical-html-renderer@1.3.39
 - @tryghost/kg-markdown-html-renderer@7.1.16
 - @tryghost/kg-mobiledoc-html-renderer@7.1.16
 - @tryghost/kg-parser-plugins@4.2.21
 - @tryghost/kg-unsplash-selector@0.3.22
 - @tryghost/kg-utils@1.0.43
 - @tryghost/koenig-lexical@1.7.23
…ESM output

The Vite 8/Rolldown migration externalized react subpaths (react/jsx-runtime,
react-dom/server) which caused two issues:
- UMD: subpaths mapped to React/ReactDOM globals that don't have the required
  exports (jsx, jsxs, renderToString)
- ESM: bundled CJS modules produced require() shims that break in browsers

Removed react-dom/server dependency entirely by replacing renderToString with
direct DOM APIs for the drop indicator and flushSync+createRoot for the drag
ghost icon. Added esmExternalRequirePlugin to convert remaining CJS
require("react") calls from bundled dependencies into ESM import references.
Updated UMD globals to map react-dom/client instead of react-dom/server.
Added --src lib flag to scope coverage to source files only, matching
the pattern used by other TypeScript-migrated packages.
 - @tryghost/html-to-mobiledoc@3.2.23
 - @tryghost/kg-default-nodes@2.0.17
 - @tryghost/kg-default-transforms@1.2.40
 - @tryghost/kg-html-to-lexical@1.2.40
 - @tryghost/kg-lexical-html-renderer@1.3.40
 - @tryghost/kg-parser-plugins@4.2.22
 - @tryghost/kg-unsplash-selector@0.3.23
 - @tryghost/koenig-lexical@1.7.24
…lector

These types are needed by consumers to properly type their onImageInsert
callbacks but were not exported from the package entry point.
 - @tryghost/kg-html-to-lexical@1.2.41
 - @tryghost/kg-unsplash-selector@0.3.24
 - @tryghost/koenig-lexical@1.7.25
 - @tryghost/html-to-mobiledoc@3.2.24
 - @tryghost/kg-clean-basic-html@4.2.22
 - @tryghost/kg-default-nodes@2.0.18
 - @tryghost/kg-default-transforms@1.2.41
 - @tryghost/kg-html-to-lexical@1.2.42
 - @tryghost/kg-lexical-html-renderer@1.3.41
 - @tryghost/kg-parser-plugins@4.2.23
 - @tryghost/kg-unsplash-selector@0.3.25
 - @tryghost/koenig-lexical@1.7.26
 - @tryghost/koenig-lexical@1.7.27
no ref
- this was not observed in the demo app because of the way the editor type was previously handled, and it wasn't clear it wasn't wired up outside of the app
 - @tryghost/kg-default-nodes@2.0.19
 - @tryghost/kg-default-transforms@1.2.42
 - @tryghost/kg-html-to-lexical@1.2.43
 - @tryghost/kg-lexical-html-renderer@1.3.42
 - @tryghost/koenig-lexical@1.7.28
sagzy and others added 13 commits July 3, 2026 06:54
Ghost no longer uses mobiledoc-based editing internals as of
ba438f2, so the
following packages have no remaining consumers in Ghost, Koenig,
or anywhere else in the TryGhost org:

- @tryghost/kg-default-atoms
- @tryghost/kg-mobiledoc-html-renderer
- @tryghost/html-to-mobiledoc
- @tryghost/kg-parser-plugins (last consumer was html-to-mobiledoc)

Removing these also drops @tryghost/mobiledoc-kit from the
dependency tree entirely.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
no issue

`yarn build-storybook` and `yarn storybook` failed with
`ReferenceError: require is not defined in ES module scope` while
loading .storybook/main.ts, and the manager build failed with an
exports mismatch from leftover Storybook 8 addons.

- replaced the `getAbsolutePath()` resolution in .storybook/main.ts
  with plain package names — the helper relied on CJS `require` which
  is unavailable in ESM scope, and absolute directory paths can't be
  imported by Node's ESM loader anyway; plain names are Storybook's
  recommended default for yarn-hoisted setups
- removed the `core.builder` override — the @storybook/react-vite
  framework already implies the vite builder in Storybook 10
- removed leftover v8/v9 addon packages (addon-essentials,
  addon-interactions, addon-actions, addon-mdx-gfm) whose features
  moved into Storybook core in v9 and which broke the manager build
- added @storybook/addon-docs, required in Storybook 10 for the
  `autodocs` tag used in preview
- removed the explicit @storybook/builder-vite dependency, now only
  used as a transitive dependency of @storybook/react-vite
no issue

CodeQL flagged two issues on the TypeScript rename PR (TryGhost/Koenig#2046); the code
is long-standing but the rename surfaced it as new code. Fixing
separately so the rename PR stays purely mechanical.

- `sanitizeHtml()`'s script/iframe placeholder regexes only matched
  strict `</script>`/`</iframe>` end tags, but per the HTML spec
  browsers also close on lax forms like `</script >` and
  `</script\t\n bar>`, so such markup skipped placeholder replacement.
  DOMPurify still stripped the elements afterwards so this wasn't
  exploitable, but the end-tag matching now mirrors browser parsing
- `dataSrcToFile()` fell back to `Math.random()` for filename
  generation when `crypto.randomUUID()` is unavailable (non-secure
  contexts); it now uses `crypto.getRandomValues()`
- Add permissive tsconfig.json (strict mode arrives with the type migration)
- Add src/vite-env.d.ts with Vite/SVG ambient declarations
- Point vite lib entry, index.html demo entry, and vitest setupFiles at renamed .ts/.tsx files
- Add __dirname ESM shim to vite configs (loaded as native ESM once .ts)
- Update playwright firefox testMatch/testIgnore regexes for .ts test files
- Parse .ts/.tsx in ESLint via typescript-eslint parser, keeping existing rules
- Ignore .d.ts files in ESLint (base no-unused-vars misfires on declarations)
- Reference vite.config.demo.ts in package.json scripts
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
- imports all 13 Koenig packages under koenig/* with full git history rewritten from packages/* via git filter-repo
- issue/PR refs in imported commit messages are qualified as TryGhost/Koenig#N to avoid mislinking against Ghost issues
- workspace integration, dependency conversion, and CI follow in subsequent commits (see docs/koenig-monorepo-merge-plan.md)
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 898 files, which is 598 over the limit of 300.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2046d75b-902b-4e30-8717-8f728a5b471d

📥 Commits

Reviewing files that changed from the base of the PR and between 158fd93 and 407ae32.

⛔ Files ignored due to path filters (131)
  • koenig/kg-default-nodes/src/nodes/at-link/kg-link.svg is excluded by !**/*.svg
  • koenig/kg-simplemde/dist/simplemde.min.css is excluded by !**/dist/**
  • koenig/kg-simplemde/dist/simplemde.min.js is excluded by !**/dist/**, !**/*.min.js
  • koenig/kg-unsplash-selector/src/assets/kg-card-type-unsplash.svg is excluded by !**/*.svg
  • koenig/kg-unsplash-selector/src/assets/kg-close.svg is excluded by !**/*.svg
  • koenig/kg-unsplash-selector/src/assets/kg-download.svg is excluded by !**/*.svg
  • koenig/kg-unsplash-selector/src/assets/kg-search.svg is excluded by !**/*.svg
  • koenig/kg-unsplash-selector/src/assets/kg-unsplash-heart.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/demo/assets/icons/kg-dollar.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/demo/assets/icons/kg-lock.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/demo/components/icons/eye-closed.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/demo/components/icons/eye-open.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/demo/components/icons/ghost-favicon.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/public/Koenig-editor-1.png is excluded by !**/*.png
  • koenig/koenig-lexical/public/Koenig-editor-2.png is excluded by !**/*.png
  • koenig/koenig-lexical/public/assets/fonts/Inter.ttf is excluded by !**/*.ttf
  • koenig/koenig-lexical/src/assets/icons/kg-add.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-align-center.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-align-left.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-arrow-down.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-arrow-top-right.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-audio-file.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-audio-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-bold.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-audio.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-bookmark.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-button.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-callout.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-codepen.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-collection.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-divider.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-email-cta.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-email.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-file.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-gallery.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-gen-embed.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-gif.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-header.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-html.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-image.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-markdown.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-nft.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-other.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-preview.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-product.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-signup.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-snippet.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-soundcloud.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-spotify.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-toggle.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-transistor.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-twitter.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-unsplash.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-video.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-vimeo.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-x.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-card-type-youtube.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-close.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-download.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-earth.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-edit.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-expand.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-eye-closed.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-eye.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-eyedropper.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-file-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-file-upload.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-gallery-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-heading-2.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-heading-3.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-help.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-img-bg.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-img-full.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-img-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-img-regular.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-img-wide.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-indicator-email.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-indicator-html.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-indicator-markdown.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-indicator-visibility.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-italic.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-layout-grid.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-layout-immersive.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-layout-list.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-layout-minimal.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-layout-split.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-link.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-play.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-product-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-quote-1.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-quote-2.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-quote.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-replace.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-search.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-shrink.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-snippet.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-star.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-swap.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-sync.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-toggle-arrow.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-trash.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-unmute.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-unsplash-heart.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-upload-fill.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-video-placeholder.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/kg-wand.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/src/assets/icons/plus.svg is excluded by !**/*.svg
  • koenig/koenig-lexical/test/e2e/fixtures/audio-sample-fail.mp3 is excluded by !**/*.mp3
  • koenig/koenig-lexical/test/e2e/fixtures/audio-sample.mp3 is excluded by !**/*.mp3
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-0.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-1.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-2.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-3.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-4.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-5.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-6.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-7.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-8.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-9.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/large-image-fail.jpeg is excluded by !**/*.jpeg
  • koenig/koenig-lexical/test/e2e/fixtures/large-image.jpeg is excluded by !**/*.jpeg
  • koenig/koenig-lexical/test/e2e/fixtures/large-image.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/e2e/fixtures/print-img-fail.pdf is excluded by !**/*.pdf
  • koenig/koenig-lexical/test/e2e/fixtures/print-img.pdf is excluded by !**/*.pdf
  • koenig/koenig-lexical/test/e2e/fixtures/video-fail.mp4 is excluded by !**/*.mp4
  • koenig/koenig-lexical/test/e2e/fixtures/video.mp4 is excluded by !**/*.mp4
  • koenig/koenig-lexical/test/e2e/plugins/assets/large.jpeg is excluded by !**/*.jpeg
  • koenig/koenig-lexical/test/e2e/plugins/assets/large.png is excluded by !**/*.png
  • koenig/koenig-lexical/test/unit/assets/large.jpeg is excluded by !**/*.jpeg
  • koenig/koenig-lexical/test/unit/assets/large.png is excluded by !**/*.png
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (898)
  • .github/scripts/publish-koenig-packages.js
  • .github/workflows/ci.yml
  • .github/workflows/koenig-demo.yml
  • .github/workflows/publish-koenig-package.yml
  • .secretlintrc.json
  • AGENTS.md
  • apps/activitypub/package.json
  • apps/admin-x-framework/package.json
  • apps/admin-x-settings/package.json
  • apps/admin/package.json
  • apps/comments-ui/package.json
  • apps/posts/package.json
  • apps/signup-form/package.json
  • compose.dev.yaml
  • docker/dev-gateway/Caddyfile
  • docker/dev-gateway/README.md
  • docker/ghost-dev/Dockerfile
  • docs/README.md
  • ghost/admin/package.json
  • ghost/core/package.json
  • ghost/core/scripts/pack.js
  • koenig/kg-card-factory/.gitignore
  • koenig/kg-card-factory/LICENSE
  • koenig/kg-card-factory/README.md
  • koenig/kg-card-factory/eslint.config.mjs
  • koenig/kg-card-factory/package.json
  • koenig/kg-card-factory/src/CardFactory.ts
  • koenig/kg-card-factory/src/index.ts
  • koenig/kg-card-factory/test/CardFactory.test.ts
  • koenig/kg-card-factory/test/utils/assertions.ts
  • koenig/kg-card-factory/test/utils/index.ts
  • koenig/kg-card-factory/test/utils/overrides.ts
  • koenig/kg-card-factory/tsconfig.cjs.json
  • koenig/kg-card-factory/tsconfig.json
  • koenig/kg-card-factory/tsconfig.test.json
  • koenig/kg-clean-basic-html/.gitignore
  • koenig/kg-clean-basic-html/LICENSE
  • koenig/kg-clean-basic-html/README.md
  • koenig/kg-clean-basic-html/eslint.config.mjs
  • koenig/kg-clean-basic-html/package.json
  • koenig/kg-clean-basic-html/src/clean-basic-html.ts
  • koenig/kg-clean-basic-html/src/index.ts
  • koenig/kg-clean-basic-html/test/clean-basic-html.test.ts
  • koenig/kg-clean-basic-html/test/utils/assertions.ts
  • koenig/kg-clean-basic-html/test/utils/index.ts
  • koenig/kg-clean-basic-html/test/utils/overrides.ts
  • koenig/kg-clean-basic-html/tsconfig.cjs.json
  • koenig/kg-clean-basic-html/tsconfig.json
  • koenig/kg-clean-basic-html/tsconfig.test.json
  • koenig/kg-converters/.gitignore
  • koenig/kg-converters/LICENSE
  • koenig/kg-converters/README.md
  • koenig/kg-converters/eslint.config.mjs
  • koenig/kg-converters/package.json
  • koenig/kg-converters/src/index.ts
  • koenig/kg-converters/src/kg-converters.ts
  • koenig/kg-converters/src/lexical-to-mobiledoc.ts
  • koenig/kg-converters/src/mobiledoc-to-lexical.ts
  • koenig/kg-converters/test/exports.test.ts
  • koenig/kg-converters/test/lexical-to-mobiledoc.test.ts
  • koenig/kg-converters/test/mobiledoc-to-lexical.test.ts
  • koenig/kg-converters/tsconfig.cjs.json
  • koenig/kg-converters/tsconfig.json
  • koenig/kg-converters/tsconfig.test.json
  • koenig/kg-default-cards/.gitignore
  • koenig/kg-default-cards/LICENSE
  • koenig/kg-default-cards/README.md
  • koenig/kg-default-cards/eslint.config.mjs
  • koenig/kg-default-cards/package.json
  • koenig/kg-default-cards/src/ambient.d.ts
  • koenig/kg-default-cards/src/cards/audio.ts
  • koenig/kg-default-cards/src/cards/before-after.ts
  • koenig/kg-default-cards/src/cards/bookmark.ts
  • koenig/kg-default-cards/src/cards/button.ts
  • koenig/kg-default-cards/src/cards/callout.ts
  • koenig/kg-default-cards/src/cards/code.ts
  • koenig/kg-default-cards/src/cards/email-cta.ts
  • koenig/kg-default-cards/src/cards/email.ts
  • koenig/kg-default-cards/src/cards/embed.ts
  • koenig/kg-default-cards/src/cards/embed/nft.ts
  • koenig/kg-default-cards/src/cards/embed/twitter.ts
  • koenig/kg-default-cards/src/cards/file.ts
  • koenig/kg-default-cards/src/cards/gallery.ts
  • koenig/kg-default-cards/src/cards/header.ts
  • koenig/kg-default-cards/src/cards/hr.ts
  • koenig/kg-default-cards/src/cards/html.ts
  • koenig/kg-default-cards/src/cards/image.ts
  • koenig/kg-default-cards/src/cards/index.ts
  • koenig/kg-default-cards/src/cards/markdown.ts
  • koenig/kg-default-cards/src/cards/paywall.ts
  • koenig/kg-default-cards/src/cards/product.ts
  • koenig/kg-default-cards/src/cards/toggle.ts
  • koenig/kg-default-cards/src/cards/video.ts
  • koenig/kg-default-cards/src/index.ts
  • koenig/kg-default-cards/src/types.d.ts
  • koenig/kg-default-cards/src/utils/dedent.ts
  • koenig/kg-default-cards/src/utils/generate-img-attrs.ts
  • koenig/kg-default-cards/src/utils/get-available-image-widths.ts
  • koenig/kg-default-cards/src/utils/hbs.ts
  • koenig/kg-default-cards/src/utils/index.ts
  • koenig/kg-default-cards/src/utils/is-local-content-image.ts
  • koenig/kg-default-cards/src/utils/is-unsplash-image.ts
  • koenig/kg-default-cards/src/utils/resize-image.ts
  • koenig/kg-default-cards/src/utils/srcset-attribute.ts
  • koenig/kg-default-cards/test/cards/audio.test.ts
  • koenig/kg-default-cards/test/cards/bookmark.test.ts
  • koenig/kg-default-cards/test/cards/button.test.ts
  • koenig/kg-default-cards/test/cards/callout.test.ts
  • koenig/kg-default-cards/test/cards/code.test.ts
  • koenig/kg-default-cards/test/cards/email-cta.test.ts
  • koenig/kg-default-cards/test/cards/email.test.ts
  • koenig/kg-default-cards/test/cards/embed.test.ts
  • koenig/kg-default-cards/test/cards/gallery.test.ts
  • koenig/kg-default-cards/test/cards/header.test.ts
  • koenig/kg-default-cards/test/cards/hr.test.ts
  • koenig/kg-default-cards/test/cards/html.test.ts
  • koenig/kg-default-cards/test/cards/image.test.ts
  • koenig/kg-default-cards/test/cards/markdown.test.ts
  • koenig/kg-default-cards/test/cards/paywall.test.ts
  • koenig/kg-default-cards/test/cards/product.test.ts
  • koenig/kg-default-cards/test/cards/toggle.test.ts
  • koenig/kg-default-cards/test/cards/video.test.ts
  • koenig/kg-default-cards/test/lib/utils/get-available-image-widths.test.ts
  • koenig/kg-default-cards/test/lib/utils/is-local-content-image.test.ts
  • koenig/kg-default-cards/test/lib/utils/is-unsplash-image.test.ts
  • koenig/kg-default-cards/test/utils/assertions.ts
  • koenig/kg-default-cards/test/utils/index.ts
  • koenig/kg-default-cards/test/utils/overrides.ts
  • koenig/kg-default-cards/tsconfig.cjs.json
  • koenig/kg-default-cards/tsconfig.json
  • koenig/kg-default-cards/tsconfig.test.json
  • koenig/kg-default-nodes/.gitignore
  • koenig/kg-default-nodes/LICENSE
  • koenig/kg-default-nodes/README.md
  • koenig/kg-default-nodes/eslint.config.mjs
  • koenig/kg-default-nodes/lib/KoenigDecoratorNode.js
  • koenig/kg-default-nodes/package.json
  • koenig/kg-default-nodes/src/KoenigDecoratorNode.ts
  • koenig/kg-default-nodes/src/export-dom.ts
  • koenig/kg-default-nodes/src/generate-decorator-node.ts
  • koenig/kg-default-nodes/src/index.ts
  • koenig/kg-default-nodes/src/kg-default-nodes.ts
  • koenig/kg-default-nodes/src/nodes/ExtendedHeadingNode.ts
  • koenig/kg-default-nodes/src/nodes/ExtendedQuoteNode.ts
  • koenig/kg-default-nodes/src/nodes/ExtendedTextNode.ts
  • koenig/kg-default-nodes/src/nodes/TKNode.ts
  • koenig/kg-default-nodes/src/nodes/aside/AsideNode.ts
  • koenig/kg-default-nodes/src/nodes/aside/AsideParser.ts
  • koenig/kg-default-nodes/src/nodes/at-link/AtLinkNode.ts
  • koenig/kg-default-nodes/src/nodes/at-link/AtLinkSearchNode.ts
  • koenig/kg-default-nodes/src/nodes/at-link/index.ts
  • koenig/kg-default-nodes/src/nodes/audio/AudioNode.ts
  • koenig/kg-default-nodes/src/nodes/audio/audio-parser.ts
  • koenig/kg-default-nodes/src/nodes/audio/audio-renderer.ts
  • koenig/kg-default-nodes/src/nodes/bookmark/BookmarkNode.ts
  • koenig/kg-default-nodes/src/nodes/bookmark/bookmark-parser.ts
  • koenig/kg-default-nodes/src/nodes/bookmark/bookmark-renderer.ts
  • koenig/kg-default-nodes/src/nodes/button/ButtonNode.ts
  • koenig/kg-default-nodes/src/nodes/button/button-parser.ts
  • koenig/kg-default-nodes/src/nodes/button/button-renderer.ts
  • koenig/kg-default-nodes/src/nodes/call-to-action/CallToActionNode.ts
  • koenig/kg-default-nodes/src/nodes/call-to-action/calltoaction-parser.ts
  • koenig/kg-default-nodes/src/nodes/call-to-action/calltoaction-renderer.ts
  • koenig/kg-default-nodes/src/nodes/callout/CalloutNode.ts
  • koenig/kg-default-nodes/src/nodes/callout/callout-parser.ts
  • koenig/kg-default-nodes/src/nodes/callout/callout-renderer.ts
  • koenig/kg-default-nodes/src/nodes/codeblock/CodeBlockNode.ts
  • koenig/kg-default-nodes/src/nodes/codeblock/codeblock-parser.ts
  • koenig/kg-default-nodes/src/nodes/codeblock/codeblock-renderer.ts
  • koenig/kg-default-nodes/src/nodes/email-cta/EmailCtaNode.ts
  • koenig/kg-default-nodes/src/nodes/email-cta/email-cta-renderer.ts
  • koenig/kg-default-nodes/src/nodes/email/EmailNode.ts
  • koenig/kg-default-nodes/src/nodes/email/email-renderer.ts
  • koenig/kg-default-nodes/src/nodes/embed/EmbedNode.ts
  • koenig/kg-default-nodes/src/nodes/embed/embed-parser.ts
  • koenig/kg-default-nodes/src/nodes/embed/embed-renderer.ts
  • koenig/kg-default-nodes/src/nodes/embed/types/twitter.ts
  • koenig/kg-default-nodes/src/nodes/file/FileNode.ts
  • koenig/kg-default-nodes/src/nodes/file/file-parser.ts
  • koenig/kg-default-nodes/src/nodes/file/file-renderer.ts
  • koenig/kg-default-nodes/src/nodes/gallery/GalleryNode.ts
  • koenig/kg-default-nodes/src/nodes/gallery/gallery-parser.ts
  • koenig/kg-default-nodes/src/nodes/gallery/gallery-renderer.ts
  • koenig/kg-default-nodes/src/nodes/header/HeaderNode.ts
  • koenig/kg-default-nodes/src/nodes/header/parsers/header-parser.ts
  • koenig/kg-default-nodes/src/nodes/header/renderers/v1/header-renderer.ts
  • koenig/kg-default-nodes/src/nodes/header/renderers/v2/header-renderer.ts
  • koenig/kg-default-nodes/src/nodes/horizontalrule/HorizontalRuleNode.ts
  • koenig/kg-default-nodes/src/nodes/horizontalrule/horizontalrule-parser.ts
  • koenig/kg-default-nodes/src/nodes/horizontalrule/horizontalrule-renderer.ts
  • koenig/kg-default-nodes/src/nodes/html/HtmlNode.ts
  • koenig/kg-default-nodes/src/nodes/html/html-parser.ts
  • koenig/kg-default-nodes/src/nodes/html/html-renderer.ts
  • koenig/kg-default-nodes/src/nodes/image/ImageNode.ts
  • koenig/kg-default-nodes/src/nodes/image/image-parser.ts
  • koenig/kg-default-nodes/src/nodes/image/image-renderer.ts
  • koenig/kg-default-nodes/src/nodes/markdown/MarkdownNode.ts
  • koenig/kg-default-nodes/src/nodes/markdown/markdown-renderer.ts
  • koenig/kg-default-nodes/src/nodes/paywall/PaywallNode.ts
  • koenig/kg-default-nodes/src/nodes/paywall/paywall-parser.ts
  • koenig/kg-default-nodes/src/nodes/paywall/paywall-renderer.ts
  • koenig/kg-default-nodes/src/nodes/product/ProductNode.ts
  • koenig/kg-default-nodes/src/nodes/product/product-parser.ts
  • koenig/kg-default-nodes/src/nodes/product/product-renderer.ts
  • koenig/kg-default-nodes/src/nodes/signup/SignupNode.ts
  • koenig/kg-default-nodes/src/nodes/signup/signup-parser.ts
  • koenig/kg-default-nodes/src/nodes/signup/signup-renderer.ts
  • koenig/kg-default-nodes/src/nodes/toggle/ToggleNode.ts
  • koenig/kg-default-nodes/src/nodes/toggle/toggle-parser.ts
  • koenig/kg-default-nodes/src/nodes/toggle/toggle-renderer.ts
  • koenig/kg-default-nodes/src/nodes/transistor/TransistorNode.ts
  • koenig/kg-default-nodes/src/nodes/transistor/transistor-renderer.ts
  • koenig/kg-default-nodes/src/nodes/video/VideoNode.ts
  • koenig/kg-default-nodes/src/nodes/video/video-parser.ts
  • koenig/kg-default-nodes/src/nodes/video/video-renderer.ts
  • koenig/kg-default-nodes/src/nodes/zwnj/ZWNJNode.ts
  • koenig/kg-default-nodes/src/serializers/linebreak.ts
  • koenig/kg-default-nodes/src/serializers/paragraph.ts
  • koenig/kg-default-nodes/src/svg.d.ts
  • koenig/kg-default-nodes/src/utils/add-create-document-option.ts
  • koenig/kg-default-nodes/src/utils/build-clean-basic-html-for-element.ts
  • koenig/kg-default-nodes/src/utils/clean-dom.ts
  • koenig/kg-default-nodes/src/utils/escape-html.ts
  • koenig/kg-default-nodes/src/utils/get-available-image-widths.ts
  • koenig/kg-default-nodes/src/utils/get-first-html-element.ts
  • koenig/kg-default-nodes/src/utils/get-resized-image-dimensions.ts
  • koenig/kg-default-nodes/src/utils/is-local-content-image.ts
  • koenig/kg-default-nodes/src/utils/is-unsplash-image.ts
  • koenig/kg-default-nodes/src/utils/read-caption-from-element.ts
  • koenig/kg-default-nodes/src/utils/read-image-attributes-from-element.ts
  • koenig/kg-default-nodes/src/utils/read-text-content.ts
  • koenig/kg-default-nodes/src/utils/render-empty-container.ts
  • koenig/kg-default-nodes/src/utils/render-helpers/email-button.ts
  • koenig/kg-default-nodes/src/utils/replacement-strings.ts
  • koenig/kg-default-nodes/src/utils/rgb-to-hex.ts
  • koenig/kg-default-nodes/src/utils/set-src-background-from-parent.ts
  • koenig/kg-default-nodes/src/utils/size-byte-converter.ts
  • koenig/kg-default-nodes/src/utils/slugify.ts
  • koenig/kg-default-nodes/src/utils/srcset-attribute.ts
  • koenig/kg-default-nodes/src/utils/tagged-template-fns.ts
  • koenig/kg-default-nodes/src/utils/truncate.ts
  • koenig/kg-default-nodes/src/utils/visibility.ts
  • koenig/kg-default-nodes/src/visibility.ts
  • koenig/kg-default-nodes/test/generate-decorator-node.test.ts
  • koenig/kg-default-nodes/test/nodes/aside.test.ts
  • koenig/kg-default-nodes/test/nodes/at-link-search.test.ts
  • koenig/kg-default-nodes/test/nodes/at-link.test.ts
  • koenig/kg-default-nodes/test/nodes/audio.test.ts
  • koenig/kg-default-nodes/test/nodes/bookmark.test.ts
  • koenig/kg-default-nodes/test/nodes/button.test.ts
  • koenig/kg-default-nodes/test/nodes/call-to-action.test.ts
  • koenig/kg-default-nodes/test/nodes/callout.test.ts
  • koenig/kg-default-nodes/test/nodes/codeblock.test.ts
  • koenig/kg-default-nodes/test/nodes/email-cta.test.ts
  • koenig/kg-default-nodes/test/nodes/email.test.ts
  • koenig/kg-default-nodes/test/nodes/embed.test.ts
  • koenig/kg-default-nodes/test/nodes/file.test.ts
  • koenig/kg-default-nodes/test/nodes/gallery.test.ts
  • koenig/kg-default-nodes/test/nodes/header.test.ts
  • koenig/kg-default-nodes/test/nodes/horizontalrule.test.ts
  • koenig/kg-default-nodes/test/nodes/html.test.ts
  • koenig/kg-default-nodes/test/nodes/image.test.ts
  • koenig/kg-default-nodes/test/nodes/markdown.test.ts
  • koenig/kg-default-nodes/test/nodes/paywall.test.ts
  • koenig/kg-default-nodes/test/nodes/product.test.ts
  • koenig/kg-default-nodes/test/nodes/signup.test.ts
  • koenig/kg-default-nodes/test/nodes/tk.test.ts
  • koenig/kg-default-nodes/test/nodes/toggle.test.ts
  • koenig/kg-default-nodes/test/nodes/transistor.test.ts
  • koenig/kg-default-nodes/test/nodes/video.test.ts
  • koenig/kg-default-nodes/test/nodes/zwnj.test.ts
  • koenig/kg-default-nodes/test/serializers/linebreak.test.ts
  • koenig/kg-default-nodes/test/serializers/paragraph.test.ts
  • koenig/kg-default-nodes/test/test-utils/assertions.ts
  • koenig/kg-default-nodes/test/test-utils/html-minifier.d.ts
  • koenig/kg-default-nodes/test/test-utils/index.ts
  • koenig/kg-default-nodes/test/test-utils/overrides.ts
  • koenig/kg-default-nodes/test/test-utils/should-assertions.d.ts
  • koenig/kg-default-nodes/test/test-utils/should.d.ts
  • koenig/kg-default-nodes/test/utils/read-caption-from-element.test.ts
  • koenig/kg-default-nodes/test/utils/rgb-to-hex.test.ts
  • koenig/kg-default-nodes/test/utils/srcset-attribute.test.ts
  • koenig/kg-default-nodes/test/utils/tagged-template-fns.test.ts
  • koenig/kg-default-nodes/test/utils/visibility.test.ts
  • koenig/kg-default-nodes/test/visibility-smoke.test.ts
  • koenig/kg-default-nodes/tsconfig.cjs.json
  • koenig/kg-default-nodes/tsconfig.json
  • koenig/kg-default-nodes/tsconfig.test.json
  • koenig/kg-default-transforms/.gitignore
  • koenig/kg-default-transforms/LICENSE
  • koenig/kg-default-transforms/README.md
  • koenig/kg-default-transforms/eslint.config.mjs
  • koenig/kg-default-transforms/package.json
  • koenig/kg-default-transforms/src/default-transforms.ts
  • koenig/kg-default-transforms/src/index.ts
  • koenig/kg-default-transforms/src/kg-default-nodes.d.ts
  • koenig/kg-default-transforms/src/transforms/denest.ts
  • koenig/kg-default-transforms/src/transforms/merge-list-nodes.ts
  • koenig/kg-default-transforms/src/transforms/remove-alignment.ts
  • koenig/kg-default-transforms/src/transforms/remove-at-link-nodes.ts
  • koenig/kg-default-transforms/src/typings.d.ts
  • koenig/kg-default-transforms/test/kg-default-transforms.test.ts
  • koenig/kg-default-transforms/test/transforms/denest.test.ts
  • koenig/kg-default-transforms/test/transforms/merge-list-nodes.test.ts
  • koenig/kg-default-transforms/test/transforms/remove-alignment.test.ts
  • koenig/kg-default-transforms/test/transforms/remove-at-link-nodes.test.ts
  • koenig/kg-default-transforms/test/utils.ts
  • koenig/kg-default-transforms/tsconfig.cjs.json
  • koenig/kg-default-transforms/tsconfig.json
  • koenig/kg-default-transforms/tsconfig.test.json
  • koenig/kg-html-to-lexical/.gitignore
  • koenig/kg-html-to-lexical/LICENSE
  • koenig/kg-html-to-lexical/README.md
  • koenig/kg-html-to-lexical/eslint.config.mjs
  • koenig/kg-html-to-lexical/package.json
  • koenig/kg-html-to-lexical/src/decs.d.ts
  • koenig/kg-html-to-lexical/src/html-to-lexical.ts
  • koenig/kg-html-to-lexical/src/index.ts
  • koenig/kg-html-to-lexical/test/html-to-lexical.test.ts
  • koenig/kg-html-to-lexical/test/sources/google-docs.test.ts
  • koenig/kg-html-to-lexical/tsconfig.cjs.json
  • koenig/kg-html-to-lexical/tsconfig.json
  • koenig/kg-html-to-lexical/tsconfig.test.json
  • koenig/kg-lexical-html-renderer/.gitignore
  • koenig/kg-lexical-html-renderer/LICENSE
  • koenig/kg-lexical-html-renderer/README.md
  • koenig/kg-lexical-html-renderer/eslint.config.mjs
  • koenig/kg-lexical-html-renderer/package.json
  • koenig/kg-lexical-html-renderer/src/LexicalHTMLRenderer.ts
  • koenig/kg-lexical-html-renderer/src/convert-to-html-string.ts
  • koenig/kg-lexical-html-renderer/src/get-dynamic-data-nodes.ts
  • koenig/kg-lexical-html-renderer/src/index.ts
  • koenig/kg-lexical-html-renderer/src/transformers/element/aside.ts
  • koenig/kg-lexical-html-renderer/src/transformers/element/blockquote.ts
  • koenig/kg-lexical-html-renderer/src/transformers/element/heading.ts
  • koenig/kg-lexical-html-renderer/src/transformers/element/list.ts
  • koenig/kg-lexical-html-renderer/src/transformers/element/paragraph.ts
  • koenig/kg-lexical-html-renderer/src/transformers/index.ts
  • koenig/kg-lexical-html-renderer/src/types.ts
  • koenig/kg-lexical-html-renderer/src/utils/TextContent.ts
  • koenig/kg-lexical-html-renderer/src/utils/generate-id.ts
  • koenig/kg-lexical-html-renderer/test/cards.test.ts
  • koenig/kg-lexical-html-renderer/test/headings.test.ts
  • koenig/kg-lexical-html-renderer/test/links.test.ts
  • koenig/kg-lexical-html-renderer/test/lists.test.ts
  • koenig/kg-lexical-html-renderer/test/quotes.test.ts
  • koenig/kg-lexical-html-renderer/test/render.test.ts
  • koenig/kg-lexical-html-renderer/test/text-formats.test.ts
  • koenig/kg-lexical-html-renderer/test/utils/assertions.ts
  • koenig/kg-lexical-html-renderer/test/utils/index.ts
  • koenig/kg-lexical-html-renderer/test/utils/overrides.ts
  • koenig/kg-lexical-html-renderer/test/utils/should-render.ts
  • koenig/kg-lexical-html-renderer/tsconfig.cjs.json
  • koenig/kg-lexical-html-renderer/tsconfig.json
  • koenig/kg-lexical-html-renderer/tsconfig.test.json
  • koenig/kg-markdown-html-renderer/.gitignore
  • koenig/kg-markdown-html-renderer/LICENSE
  • koenig/kg-markdown-html-renderer/README.md
  • koenig/kg-markdown-html-renderer/eslint.config.mjs
  • koenig/kg-markdown-html-renderer/package.json
  • koenig/kg-markdown-html-renderer/src/index.ts
  • koenig/kg-markdown-html-renderer/src/markdown-html-renderer.ts
  • koenig/kg-markdown-html-renderer/src/types.d.ts
  • koenig/kg-markdown-html-renderer/test/markdown-html-renderer.test.ts
  • koenig/kg-markdown-html-renderer/test/utils/assertions.ts
  • koenig/kg-markdown-html-renderer/test/utils/index.ts
  • koenig/kg-markdown-html-renderer/test/utils/overrides.ts
  • koenig/kg-markdown-html-renderer/tsconfig.cjs.json
  • koenig/kg-markdown-html-renderer/tsconfig.json
  • koenig/kg-markdown-html-renderer/tsconfig.test.json
  • koenig/kg-simplemde/.gitignore
  • koenig/kg-simplemde/.nvmrc
  • koenig/kg-simplemde/.travis.yml
  • koenig/kg-simplemde/CONTRIBUTING.md
  • koenig/kg-simplemde/LICENSE
  • koenig/kg-simplemde/README.md
  • koenig/kg-simplemde/bower.json
  • koenig/kg-simplemde/debug/simplemde.css
  • koenig/kg-simplemde/debug/simplemde.debug.js
  • koenig/kg-simplemde/debug/simplemde.js
  • koenig/kg-simplemde/gulpfile.js
  • koenig/kg-simplemde/package.json
  • koenig/kg-simplemde/src/css/simplemde.css
  • koenig/kg-simplemde/src/js/codemirror/tablist.js
  • koenig/kg-simplemde/src/js/simplemde.js
  • koenig/kg-unsplash-selector/.gitignore
  • koenig/kg-unsplash-selector/LICENSE
  • koenig/kg-unsplash-selector/README.md
  • koenig/kg-unsplash-selector/demo/App.tsx
  • koenig/kg-unsplash-selector/demo/demo.tsx
  • koenig/kg-unsplash-selector/demo/vite-env.d.ts
  • koenig/kg-unsplash-selector/eslint.config.js
  • koenig/kg-unsplash-selector/index.html
  • koenig/kg-unsplash-selector/package.json
  • koenig/kg-unsplash-selector/playwright.config.js
  • koenig/kg-unsplash-selector/postcss.config.cjs
  • koenig/kg-unsplash-selector/src/UnsplashSearchModal.tsx
  • koenig/kg-unsplash-selector/src/UnsplashTypes.ts
  • koenig/kg-unsplash-selector/src/api/IUnsplashProvider.ts
  • koenig/kg-unsplash-selector/src/api/InMemoryUnsplashProvider.ts
  • koenig/kg-unsplash-selector/src/api/MasonryService.ts
  • koenig/kg-unsplash-selector/src/api/PhotoUseCase.ts
  • koenig/kg-unsplash-selector/src/api/UnsplashProvider.ts
  • koenig/kg-unsplash-selector/src/api/UnsplashService.ts
  • koenig/kg-unsplash-selector/src/api/dataFixtures.json
  • koenig/kg-unsplash-selector/src/api/unsplashFixtures.ts
  • koenig/kg-unsplash-selector/src/index.ts
  • koenig/kg-unsplash-selector/src/styles/index.css
  • koenig/kg-unsplash-selector/src/ui/UnsplashButton.tsx
  • koenig/kg-unsplash-selector/src/ui/UnsplashGallery.tsx
  • koenig/kg-unsplash-selector/src/ui/UnsplashImage.tsx
  • koenig/kg-unsplash-selector/src/ui/UnsplashSelector.tsx
  • koenig/kg-unsplash-selector/src/ui/UnsplashZoomed.tsx
  • koenig/kg-unsplash-selector/src/vite-env.d.ts
  • koenig/kg-unsplash-selector/tailwind.config.cjs
  • koenig/kg-unsplash-selector/test/acceptance/modal.test.ts
  • koenig/kg-unsplash-selector/test/unit/Masonry.test.ts
  • koenig/kg-unsplash-selector/test/unit/UnsplashService.test.ts
  • koenig/kg-unsplash-selector/tsconfig.declaration.json
  • koenig/kg-unsplash-selector/tsconfig.json
  • koenig/kg-unsplash-selector/tsconfig.node.json
  • koenig/kg-unsplash-selector/tsconfig.test.json
  • koenig/kg-unsplash-selector/vite.config.ts
  • koenig/kg-unsplash-selector/vitest.config.ts
  • koenig/kg-utils/.gitignore
  • koenig/kg-utils/LICENSE
  • koenig/kg-utils/README.md
  • koenig/kg-utils/eslint.config.mjs
  • koenig/kg-utils/package.json
  • koenig/kg-utils/src/index.ts
  • koenig/kg-utils/src/slugify.ts
  • koenig/kg-utils/test/slugify.test.ts
  • koenig/kg-utils/test/utils/assertions.ts
  • koenig/kg-utils/test/utils/index.ts
  • koenig/kg-utils/test/utils/overrides.ts
  • koenig/kg-utils/tsconfig.cjs.json
  • koenig/kg-utils/tsconfig.json
  • koenig/kg-utils/tsconfig.test.json
  • koenig/koenig-lexical/.gitignore
  • koenig/koenig-lexical/.storybook/editorEmptyState.ts
  • koenig/koenig-lexical/.storybook/main.ts
  • koenig/koenig-lexical/.storybook/preview-head.html
  • koenig/koenig-lexical/.storybook/preview.tsx
  • koenig/koenig-lexical/.stylelintrc.json
  • koenig/koenig-lexical/CLAUDE.md
  • koenig/koenig-lexical/LICENSE
  • koenig/koenig-lexical/README.md
  • koenig/koenig-lexical/demo/DemoApp.tsx
  • koenig/koenig-lexical/demo/HtmlOutputDemo.tsx
  • koenig/koenig-lexical/demo/RestrictedContentDemo.tsx
  • koenig/koenig-lexical/demo/components/DarkModeToggle.tsx
  • koenig/koenig-lexical/demo/components/EmailEditorWrapper.tsx
  • koenig/koenig-lexical/demo/components/FloatingButton.tsx
  • koenig/koenig-lexical/demo/components/InitialContentToggle.tsx
  • koenig/koenig-lexical/demo/components/Navigator.tsx
  • koenig/koenig-lexical/demo/components/SerializedStateTextarea.tsx
  • koenig/koenig-lexical/demo/components/Sidebar.tsx
  • koenig/koenig-lexical/demo/components/TitleTextBox.tsx
  • koenig/koenig-lexical/demo/components/TreeView.tsx
  • koenig/koenig-lexical/demo/components/Watermark.tsx
  • koenig/koenig-lexical/demo/components/WordCount.tsx
  • koenig/koenig-lexical/demo/content/basic-content.json
  • koenig/koenig-lexical/demo/content/content.json
  • koenig/koenig-lexical/demo/content/email-content.json
  • koenig/koenig-lexical/demo/content/minimal-content.json
  • koenig/koenig-lexical/demo/demo.tsx
  • koenig/koenig-lexical/demo/styles/demo.css
  • koenig/koenig-lexical/demo/utils/fetchEmbed.ts
  • koenig/koenig-lexical/demo/utils/gifConfig.ts
  • koenig/koenig-lexical/demo/utils/unsplashConfig.ts
  • koenig/koenig-lexical/demo/utils/useFileUpload.ts
  • koenig/koenig-lexical/demo/utils/useSnippets.ts
  • koenig/koenig-lexical/eslint.config.mjs
  • koenig/koenig-lexical/index.html
  • koenig/koenig-lexical/package.json
  • koenig/koenig-lexical/playwright.config.ts
  • koenig/koenig-lexical/postcss.config.cjs
  • koenig/koenig-lexical/src/components/DesignSandbox.tsx
  • koenig/koenig-lexical/src/components/EmailEditor.tsx
  • koenig/koenig-lexical/src/components/KoenigCaptionEditor.tsx
  • koenig/koenig-lexical/src/components/KoenigCardWrapper.tsx
  • koenig/koenig-lexical/src/components/KoenigComposableEditor.tsx
  • koenig/koenig-lexical/src/components/KoenigComposer.tsx
  • koenig/koenig-lexical/src/components/KoenigEditor.tsx
  • koenig/koenig-lexical/src/components/KoenigErrorBoundary.tsx
  • koenig/koenig-lexical/src/components/KoenigNestedComposer.tsx
  • koenig/koenig-lexical/src/components/KoenigNestedEditor.tsx
  • koenig/koenig-lexical/src/components/ui/ActionToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/AtLinkResultsPopup.tsx
  • koenig/koenig-lexical/src/components/ui/AudioUploadForm.tsx
  • koenig/koenig-lexical/src/components/ui/BackgroundImagePicker.tsx
  • koenig/koenig-lexical/src/components/ui/Button.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Button.tsx
  • koenig/koenig-lexical/src/components/ui/ButtonGroup.stories.tsx
  • koenig/koenig-lexical/src/components/ui/ButtonGroup.tsx
  • koenig/koenig-lexical/src/components/ui/CardCaptionEditor.tsx
  • koenig/koenig-lexical/src/components/ui/CardMenu.stories.tsx
  • koenig/koenig-lexical/src/components/ui/CardMenu.tsx
  • koenig/koenig-lexical/src/components/ui/CardVisibilityMessage.tsx
  • koenig/koenig-lexical/src/components/ui/CardWrapper.tsx
  • koenig/koenig-lexical/src/components/ui/ColorOptionButtons.tsx
  • koenig/koenig-lexical/src/components/ui/ColorPicker.stories.tsx
  • koenig/koenig-lexical/src/components/ui/ColorPicker.tsx
  • koenig/koenig-lexical/src/components/ui/Delayed.tsx
  • koenig/koenig-lexical/src/components/ui/Dropdown.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Dropdown.tsx
  • koenig/koenig-lexical/src/components/ui/DropdownContainer.tsx
  • koenig/koenig-lexical/src/components/ui/EditorPlaceholder.tsx
  • koenig/koenig-lexical/src/components/ui/EmojiPicker.tsx
  • koenig/koenig-lexical/src/components/ui/EmojiPickerPortal.tsx
  • koenig/koenig-lexical/src/components/ui/FileUploadForm.tsx
  • koenig/koenig-lexical/src/components/ui/FloatingFormatToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/FloatingLinkToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/FloatingToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/FormatToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/GifPlugin.tsx
  • koenig/koenig-lexical/src/components/ui/GifSelector.stories.tsx
  • koenig/koenig-lexical/src/components/ui/GifSelector.tsx
  • koenig/koenig-lexical/src/components/ui/HighlightedString.tsx
  • koenig/koenig-lexical/src/components/ui/IconButton.stories.tsx
  • koenig/koenig-lexical/src/components/ui/IconButton.tsx
  • koenig/koenig-lexical/src/components/ui/ImageUploadForm.tsx
  • koenig/koenig-lexical/src/components/ui/ImageUploadSwatch.tsx
  • koenig/koenig-lexical/src/components/ui/Input.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Input.tsx
  • koenig/koenig-lexical/src/components/ui/InputList.stories.tsx
  • koenig/koenig-lexical/src/components/ui/InputList.tsx
  • koenig/koenig-lexical/src/components/ui/KeyboardSelection.tsx
  • koenig/koenig-lexical/src/components/ui/KeyboardSelectionWithGroups.tsx
  • koenig/koenig-lexical/src/components/ui/LinkActionToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/LinkActionToolbarWithSearch.tsx
  • koenig/koenig-lexical/src/components/ui/LinkInput.stories.tsx
  • koenig/koenig-lexical/src/components/ui/LinkInput.tsx
  • koenig/koenig-lexical/src/components/ui/LinkInputSearchItem.tsx
  • koenig/koenig-lexical/src/components/ui/LinkInputWithSearch.stories.tsx
  • koenig/koenig-lexical/src/components/ui/LinkInputWithSearch.tsx
  • koenig/koenig-lexical/src/components/ui/LinkToolbar.stories.tsx
  • koenig/koenig-lexical/src/components/ui/LinkToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/MediaPlaceholder.stories.tsx
  • koenig/koenig-lexical/src/components/ui/MediaPlaceholder.tsx
  • koenig/koenig-lexical/src/components/ui/MediaPlayer.stories.tsx
  • koenig/koenig-lexical/src/components/ui/MediaPlayer.tsx
  • koenig/koenig-lexical/src/components/ui/MediaUploader.tsx
  • koenig/koenig-lexical/src/components/ui/Modal.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Modal.tsx
  • koenig/koenig-lexical/src/components/ui/MultiSelectDropdown.tsx
  • koenig/koenig-lexical/src/components/ui/PlusMenu.stories.tsx
  • koenig/koenig-lexical/src/components/ui/PlusMenu.tsx
  • koenig/koenig-lexical/src/components/ui/Portal.tsx
  • koenig/koenig-lexical/src/components/ui/ProgressBar.stories.tsx
  • koenig/koenig-lexical/src/components/ui/ProgressBar.tsx
  • koenig/koenig-lexical/src/components/ui/ReadOnlyOverlay.tsx
  • koenig/koenig-lexical/src/components/ui/SettingsPanel.stories.tsx
  • koenig/koenig-lexical/src/components/ui/SettingsPanel.tsx
  • koenig/koenig-lexical/src/components/ui/SlashMenu.tsx
  • koenig/koenig-lexical/src/components/ui/Slider.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Slider.tsx
  • koenig/koenig-lexical/src/components/ui/SnippetActionToolbar.tsx
  • koenig/koenig-lexical/src/components/ui/SnippetInput.stories.tsx
  • koenig/koenig-lexical/src/components/ui/SnippetInput.tsx
  • koenig/koenig-lexical/src/components/ui/SnippetInput/Dropdown.tsx
  • koenig/koenig-lexical/src/components/ui/SnippetInput/Input.tsx
  • koenig/koenig-lexical/src/components/ui/Spinner.tsx
  • koenig/koenig-lexical/src/components/ui/SubscribeForm.stories.tsx
  • koenig/koenig-lexical/src/components/ui/SubscribeForm.tsx
  • koenig/koenig-lexical/src/components/ui/TabView.tsx
  • koenig/koenig-lexical/src/components/ui/TextInput.tsx
  • koenig/koenig-lexical/src/components/ui/Toggle.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Toggle.tsx
  • koenig/koenig-lexical/src/components/ui/ToolbarMenu.stories.tsx
  • koenig/koenig-lexical/src/components/ui/ToolbarMenu.tsx
  • koenig/koenig-lexical/src/components/ui/ToolbarMenuItem.stories.tsx
  • koenig/koenig-lexical/src/components/ui/Tooltip.tsx
  • koenig/koenig-lexical/src/components/ui/UnsplashPlugin.tsx
  • koenig/koenig-lexical/src/components/ui/UrlInput.stories.tsx
  • koenig/koenig-lexical/src/components/ui/UrlInput.tsx
  • koenig/koenig-lexical/src/components/ui/UrlSearchInput.stories.tsx
  • koenig/koenig-lexical/src/components/ui/UrlSearchInput.tsx
  • koenig/koenig-lexical/src/components/ui/VisibilitySettings.tsx
  • koenig/koenig-lexical/src/components/ui/cards/AudioCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/AudioCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/BookmarkCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/BookmarkCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ButtonCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ButtonCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CallToActionCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CallToActionCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CalloutCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CalloutCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CodeBlockCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/CodeBlockCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmailCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmailCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmailCtaCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmailCtaCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmbedCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/EmbedCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/FileCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/FileCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/GalleryCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/GalleryCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HeaderCard/v1/HeaderCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HeaderCard/v1/HeaderCard.v1.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HeaderCard/v2/HeaderCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HeaderCard/v2/HeaderCard.v2.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HorizontalRuleCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HorizontalRuleCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HtmlCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HtmlCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/HtmlCard/HtmlEditor.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ImageCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ImageCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard/MarkdownEditor.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard/MarkdownHelpDialog.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard/MarkdownImageUploader.tsx
  • koenig/koenig-lexical/src/components/ui/cards/MarkdownCard/useMarkdownImageUploader.ts
  • koenig/koenig-lexical/src/components/ui/cards/PaywallCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/PaywallCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ProductCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ProductCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ProductCard/ProductCardImage.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ProductCard/RatingButton.tsx
  • koenig/koenig-lexical/src/components/ui/cards/SignupCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/SignupCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ToggleCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/ToggleCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/TransistorCard.tsx
  • koenig/koenig-lexical/src/components/ui/cards/VideoCard.stories.tsx
  • koenig/koenig-lexical/src/components/ui/cards/VideoCard.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Gif/Error.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Gif/Gif.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Gif/Loader.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashButton.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashGallery.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashImage.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashSelector.stories.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashSelector.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/Unsplash/UnsplashZoomed.tsx
  • koenig/koenig-lexical/src/components/ui/file-selectors/UnsplashModal.tsx
  • koenig/koenig-lexical/src/context/CardContext.tsx
  • koenig/koenig-lexical/src/context/KoenigComposerContext.tsx
  • koenig/koenig-lexical/src/context/KoenigSelectedCardContext.tsx
  • koenig/koenig-lexical/src/context/SharedHistoryContext.tsx
  • koenig/koenig-lexical/src/context/SharedOnChangeContext.tsx
  • koenig/koenig-lexical/src/context/TKContext.tsx
  • koenig/koenig-lexical/src/hooks/useCardDragAndDrop.ts
  • koenig/koenig-lexical/src/hooks/useClickOutside.ts
  • koenig/koenig-lexical/src/hooks/useFileDragAndDrop.ts
  • koenig/koenig-lexical/src/hooks/useGalleryReorder.ts
  • koenig/koenig-lexical/src/hooks/useInputSelection.ts
  • koenig/koenig-lexical/src/hooks/useKoenigTextEntity.ts
  • koenig/koenig-lexical/src/hooks/useMovable.ts
  • koenig/koenig-lexical/src/hooks/usePinturaEditor.ts
  • koenig/koenig-lexical/src/hooks/usePreviousFocus.ts
  • koenig/koenig-lexical/src/hooks/useSearchLinks.ts
  • koenig/koenig-lexical/src/hooks/useSettingsPanelReposition.ts
  • koenig/koenig-lexical/src/hooks/useTypeaheadTriggerMatch.ts
  • koenig/koenig-lexical/src/hooks/useVisibilityToggle.ts
  • koenig/koenig-lexical/src/index.ts
  • koenig/koenig-lexical/src/nodes/AsideNode.ts
  • koenig/koenig-lexical/src/nodes/AudioNode.tsx
  • koenig/koenig-lexical/src/nodes/AudioNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/BasicNodes.ts
  • koenig/koenig-lexical/src/nodes/BookmarkNode.tsx
  • koenig/koenig-lexical/src/nodes/BookmarkNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/ButtonNode.tsx
  • koenig/koenig-lexical/src/nodes/ButtonNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/CallToActionNode.tsx
  • koenig/koenig-lexical/src/nodes/CallToActionNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/CalloutNode.tsx
  • koenig/koenig-lexical/src/nodes/CalloutNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/CodeBlockNode.tsx
  • koenig/koenig-lexical/src/nodes/CodeBlockNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/DefaultNodes.ts
  • koenig/koenig-lexical/src/nodes/EmailCtaNode.tsx
  • koenig/koenig-lexical/src/nodes/EmailCtaNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/EmailEditorNodes.ts
  • koenig/koenig-lexical/src/nodes/EmailEmbedNode.tsx
  • koenig/koenig-lexical/src/nodes/EmailNode.tsx
  • koenig/koenig-lexical/src/nodes/EmailNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/EmailNodes.ts
  • koenig/koenig-lexical/src/nodes/EmbedNode.tsx
  • koenig/koenig-lexical/src/nodes/EmbedNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/FileNode.tsx
  • koenig/koenig-lexical/src/nodes/FileNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/GalleryNode.tsx
  • koenig/koenig-lexical/src/nodes/GalleryNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/HeaderNode.tsx
  • koenig/koenig-lexical/src/nodes/HorizontalRuleNode.tsx
  • koenig/koenig-lexical/src/nodes/HtmlNode.tsx
  • koenig/koenig-lexical/src/nodes/HtmlNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/ImageNode.tsx
  • koenig/koenig-lexical/src/nodes/ImageNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/MarkdownNode.tsx
  • koenig/koenig-lexical/src/nodes/MarkdownNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/MinimalNodes.ts
  • koenig/koenig-lexical/src/nodes/PaywallNode.tsx
  • koenig/koenig-lexical/src/nodes/ProductNode.tsx
  • koenig/koenig-lexical/src/nodes/ProductNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/SignupNode.tsx
  • koenig/koenig-lexical/src/nodes/SignupNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/ToggleNode.tsx
  • koenig/koenig-lexical/src/nodes/ToggleNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/TransistorNode.tsx
  • koenig/koenig-lexical/src/nodes/TransistorNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/VideoNode.tsx
  • koenig/koenig-lexical/src/nodes/VideoNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/header/v1/HeaderNodeComponent.tsx
  • koenig/koenig-lexical/src/nodes/header/v2/HeaderNodeComponent.tsx
  • koenig/koenig-lexical/src/plugins/AllDefaultPlugins.tsx
  • koenig/koenig-lexical/src/plugins/AtLinkPlugin.tsx
  • koenig/koenig-lexical/src/plugins/AudioPlugin.tsx
  • koenig/koenig-lexical/src/plugins/BookmarkPlugin.tsx
  • koenig/koenig-lexical/src/plugins/ButtonPlugin.tsx
  • koenig/koenig-lexical/src/plugins/CallToActionPlugin.tsx
  • koenig/koenig-lexical/src/plugins/CalloutPlugin.tsx
  • koenig/koenig-lexical/src/plugins/CardMenuPlugin.tsx
  • koenig/koenig-lexical/src/plugins/DragDropPastePlugin.tsx
  • koenig/koenig-lexical/src/plugins/DragDropReorderPlugin.tsx
  • koenig/koenig-lexical/src/plugins/EmEnDashPlugin.tsx
  • koenig/koenig-lexical/src/plugins/EmailCtaPlugin.tsx
  • koenig/koenig-lexical/src/plugins/EmailPlugin.tsx
  • koenig/koenig-lexical/src/plugins/EmbedPlugin.tsx
  • koenig/koenig-lexical/src/plugins/EmojiPickerPlugin.tsx
  • koenig/koenig-lexical/src/plugins/ExternalControlPlugin.tsx
  • koenig/koenig-lexical/src/plugins/FilePlugin.tsx
  • koenig/koenig-lexical/src/plugins/FloatingToolbarPlugin.tsx
  • koenig/koenig-lexical/src/plugins/GalleryPlugin.tsx
  • koenig/koenig-lexical/src/plugins/HeaderPlugin.tsx
  • koenig/koenig-lexical/src/plugins/HorizontalRulePlugin.tsx
  • koenig/koenig-lexical/src/plugins/HtmlOutputPlugin.tsx
  • koenig/koenig-lexical/src/plugins/HtmlPlugin.tsx
  • koenig/koenig-lexical/src/plugins/ImagePlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigBehaviourPlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigBlurPlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigFocusPlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigNestedEditorPlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigSelectorPlugin.tsx
  • koenig/koenig-lexical/src/plugins/KoenigSnippetPlugin.tsx
  • koenig/koenig-lexical/src/plugins/MarkdownPastePlugin.tsx
  • koenig/koenig-lexical/src/plugins/MarkdownPlugin.tsx
  • koenig/koenig-lexical/src/plugins/MarkdownShortcutPlugin.tsx
  • koenig/koenig-lexical/src/plugins/PaywallPlugin.tsx
  • koenig/koenig-lexical/src/plugins/PlusCardMenuPlugin.tsx
  • koenig/koenig-lexical/src/plugins/ProductPlugin.tsx
  • koenig/koenig-lexical/src/plugins/ReplacementStringsPlugin.tsx
  • koenig/koenig-lexical/src/plugins/RestrictContentPlugin.tsx
  • koenig/koenig-lexical/src/plugins/SignupPlugin.tsx
  • koenig/koenig-lexical/src/plugins/SlashCardMenuPlugin.tsx
  • koenig/koenig-lexical/src/plugins/TKCountPlugin.tsx
  • koenig/koenig-lexical/src/plugins/TKPlugin.tsx
  • koenig/koenig-lexical/src/plugins/TogglePlugin.tsx
  • koenig/koenig-lexical/src/plugins/TransistorPlugin.tsx
  • koenig/koenig-lexical/src/plugins/VideoPlugin.tsx
  • koenig/koenig-lexical/src/plugins/WordCountPlugin.tsx
  • koenig/koenig-lexical/src/styles/components/kg-prose.css
  • koenig/koenig-lexical/src/styles/components/koenig-lexical.css
  • koenig/koenig-lexical/src/styles/components/react-colorful.css
  • koenig/koenig-lexical/src/styles/components/simplemde.css
  • koenig/koenig-lexical/src/styles/index.css
  • koenig/koenig-lexical/src/styles/preflight.css
  • koenig/koenig-lexical/src/themes/default.ts
  • koenig/koenig-lexical/src/utils/$getSelectionRangeRect.ts
  • koenig/koenig-lexical/src/utils/$insertAndSelectNode.ts
  • koenig/koenig-lexical/src/utils/$isAtStartOfDocument.ts
  • koenig/koenig-lexical/src/utils/$isAtTopOfNode.ts
  • koenig/koenig-lexical/src/utils/$selectDecoratorNode.ts
  • koenig/koenig-lexical/src/utils/analytics.ts
  • koenig/koenig-lexical/src/utils/audioUploadHandler.ts
  • koenig/koenig-lexical/src/utils/autoExpandTextArea.ts
  • koenig/koenig-lexical/src/utils/buildCardMenu.ts
  • koenig/koenig-lexical/src/utils/callToActionColors.ts
  • koenig/koenig-lexical/src/utils/codemirror-config.ts
  • koenig/koenig-lexical/src/utils/constants.ts
  • koenig/koenig-lexical/src/utils/ctrlOrCmd.ts
  • koenig/koenig-lexical/src/utils/dataSrcToFile.ts
  • koenig/koenig-lexical/src/utils/draggable/DragDropContainer.ts
  • koenig/koenig-lexical/src/utils/draggable/DragDropHandler.tsx
  • koenig/koenig-lexical/src/utils/draggable/ScrollHandler.ts
  • koenig/koenig-lexical/src/utils/draggable/draggable-constants.ts
  • koenig/koenig-lexical/src/utils/draggable/draggable-utils.ts
  • koenig/koenig-lexical/src/utils/extractVideoMetadata.ts
  • koenig/koenig-lexical/src/utils/fileUploadHandler.ts
  • koenig/koenig-lexical/src/utils/generateEditorState.ts
  • koenig/koenig-lexical/src/utils/getAccentColor.ts
  • koenig/koenig-lexical/src/utils/getAudioMetadata.ts
  • koenig/koenig-lexical/src/utils/getDOMRangeRect.ts
  • koenig/koenig-lexical/src/utils/getEditorCardNodes.ts
  • koenig/koenig-lexical/src/utils/getImageDimensions.ts
  • koenig/koenig-lexical/src/utils/getImageFilenameFromSrc.ts
  • koenig/koenig-lexical/src/utils/getScrollParent.ts
  • koenig/koenig-lexical/src/utils/getSelectedNode.ts
  • koenig/koenig-lexical/src/utils/getTopLevelNativeElement.ts
  • koenig/koenig-lexical/src/utils/image-card-widths.ts
  • koenig/koenig-lexical/src/utils/imageUploadHandler.ts
  • koenig/koenig-lexical/src/utils/index.ts
  • koenig/koenig-lexical/src/utils/isEditorEmpty.ts
  • koenig/koenig-lexical/src/utils/isGif.ts
  • koenig/koenig-lexical/src/utils/isInternalUrl.ts
  • koenig/koenig-lexical/src/utils/nested-editors.ts
  • koenig/koenig-lexical/src/utils/openFileSelection.ts
  • koenig/koenig-lexical/src/utils/prettifyFileName.ts
  • koenig/koenig-lexical/src/utils/sanitize-html.ts
  • koenig/koenig-lexical/src/utils/services/gif.ts
  • koenig/koenig-lexical/src/utils/setFloatingElemPosition.ts
  • koenig/koenig-lexical/src/utils/shortcutSymbols.ts
  • koenig/koenig-lexical/src/utils/shouldIgnoreEvent.ts
  • koenig/koenig-lexical/src/utils/storybook/populate-storybook-editor.ts
  • koenig/koenig-lexical/src/utils/thumbnailUploadHandler.ts
  • koenig/koenig-lexical/src/utils/visibility.ts
  • koenig/koenig-lexical/src/vite-env.d.ts
  • koenig/koenig-lexical/svgo.config.cjs
  • koenig/koenig-lexical/tailwind.config.cjs
  • koenig/koenig-lexical/test/e2e/card-behaviour.test.ts
  • koenig/koenig-lexical/test/e2e/cards/audio-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/bookmark-card-with-search.test.ts
  • koenig/koenig-lexical/test/e2e/cards/bookmark-card-without-search.test.ts
  • koenig/koenig-lexical/test/e2e/cards/button-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/call-to-action-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/callout-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/code-block-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/email-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/email-cta-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/embed-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/file-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/gallery-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/header-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/html-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/image-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/markdown-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/paywall-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/product-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/signup-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/toggle-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/transistor-card.test.ts
  • koenig/koenig-lexical/test/e2e/cards/video-card.firefox.test.ts
  • koenig/koenig-lexical/test/e2e/content-visibility.test.ts
  • koenig/koenig-lexical/test/e2e/editors/basic-editor.test.ts
  • koenig/koenig-lexical/test/e2e/editors/email-editor.test.ts
  • koenig/koenig-lexical/test/e2e/editors/minimal-editor.test.ts
  • koenig/koenig-lexical/test/e2e/fixtures/paste/google-docs-empty-paragraphs.html
  • koenig/koenig-lexical/test/e2e/fixtures/paste/office-com-headings.html
  • koenig/koenig-lexical/test/e2e/fixtures/paste/office-com-text-formats.html
  • koenig/koenig-lexical/test/e2e/floating-toolbar.test.ts
  • koenig/koenig-lexical/test/e2e/format-shortcuts.test.ts
  • koenig/koenig-lexical/test/e2e/linking.test.ts
  • koenig/koenig-lexical/test/e2e/list-behaviour.test.ts
  • koenig/koenig-lexical/test/e2e/modals/UnsplashSelector.test.ts
  • koenig/koenig-lexical/test/e2e/node-transforms.test.ts
  • koenig/koenig-lexical/test/e2e/paste-behaviour.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/DragDropPastePlugin.firefox.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/DragDropPastePlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/DragDropReorderPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/EmojiPickerPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/HtmlOutputPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/KoenigSnippetPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/ReplacementStringsPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/RestrictContentPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/TKPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plugins/WordCountPlugin.test.ts
  • koenig/koenig-lexical/test/e2e/plus-button.test.ts
  • koenig/koenig-lexical/test/e2e/selection.test.ts
  • koenig/koenig-lexical/test/e2e/slash-menu.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/code-block.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/emdash-endash.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/headings.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/horizontal-line-rule.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/links.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/markdown.test.ts
  • koenig/koenig-lexical/test/e2e/text-transforms/paywall.test.ts
  • koenig/koenig-lexical/test/e2e/title-behaviour.test.ts
  • koenig/koenig-lexical/test/e2e/utils/getImageDimensions.test.ts
  • koenig/koenig-lexical/test/test-setup.ts
  • koenig/koenig-lexical/test/unit/EmailEditor.test.ts
  • koenig/koenig-lexical/test/unit/KoenigComposer.test.tsx
  • koenig/koenig-lexical/test/unit/build-output.test.ts
  • koenig/koenig-lexical/test/unit/buildCardMenu.test.ts
  • koenig/koenig-lexical/test/unit/headerCardv2.test.ts
  • koenig/koenig-lexical/test/unit/hooks/useVisibilityToggle.test.ts
  • koenig/koenig-lexical/test/unit/productCard.test.ts
  • koenig/koenig-lexical/test/unit/signupCard.test.ts
  • koenig/koenig-lexical/test/unit/toggleCard.test.ts
  • koenig/koenig-lexical/test/unit/utils/generateEditorState.test.ts
  • koenig/koenig-lexical/test/unit/utils/gif-provider.test.ts
  • koenig/koenig-lexical/test/unit/utils/image-card-widths.test.ts
  • koenig/koenig-lexical/test/unit/utils/sanitize-html.test.ts
  • koenig/koenig-lexical/test/unit/utils/visibility.test.ts
  • koenig/koenig-lexical/test/utils/color-select-helper.ts
  • koenig/koenig-lexical/test/utils/e2e.ts
  • koenig/koenig-lexical/test/utils/isTestEnv.ts
  • koenig/koenig-lexical/tsconfig.json
  • koenig/koenig-lexical/vite.config.demo.ts
  • koenig/koenig-lexical/vite.config.ts
  • nx.json
  • package.json
  • pnpm-workspace.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch koenig-monorepo-merge

@nx-cloud

nx-cloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit df3249f

Command Status Duration Result
nx run @tryghost/admin-x-settings:test:acceptance ✅ Succeeded 10m 25s View ↗
nx run ghost:test:ci:integration ✅ Succeeded 4s View ↗
nx run ghost:test:integration ✅ Succeeded 1m 37s View ↗
nx run ghost:test:legacy ✅ Succeeded 2m 56s View ↗
nx run @tryghost/koenig-lexical:test:acceptance ✅ Succeeded 2m 34s View ↗
nx run ghost:test:e2e ✅ Succeeded 1m 35s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded <1s View ↗
nx run @tryghost/activitypub:test:acceptance ✅ Succeeded 50s View ↗
Additional runs (9) ✅ Succeeded ... View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-07-08 11:59:51 UTC

end = end.replace(/(\*\*|__)/, "");
} else if(type == "italic") {
start = start.replace(/(\*|_)(?![\s\S]*(\*|_))/, "");
end = end.replace(/(\*|_)/, "");
/\s*editor-preview-active\s*/g, ""
);
if(toolbar) {
toolbar.className = toolbar.className.replace(/\s*active\s*/g, "");
);
var toolbar = editor.toolbarElements.preview;
var toolbar_div = wrapper.previousSibling;
toolbar.className = toolbar.className.replace(/\s*active\s*/g, "");
preview.className = preview.className.replace(
/\s*editor-preview-active-side\s*/g, ""
);
toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, "");
if(!/active/.test(toolbarButton.className)) {
toolbarButton.className += " active";
} else {
toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, "");
let type = 'text';
let data = content.slice(entity.start, entity.end + 1).join('').replace(/\n/g, '<br>');
if (entity.url) {
if (!entity.display_url || entity.display_url.startsWith('pic.twitter.com')) {
let type = 'text';
let data = content.slice(entity.start, entity.end + 1).join('').replace(/\n/g, '<br>');
if (entity.url) {
if (!entity.display_url || entity.display_url.startsWith('pic.twitter.com')) {
}

function removeCodeWrappers(html: string): string {
return html.replace(/<code\b[^>]*>((.*?){.*?}(.*?))<\/code>/gi, '$1');
};

export function render(markdown: string, options: RenderOptions = {}): string {
return selectRenderer(options).render(markdown);
) {
target[property] = _mergeProperties(target[property] || {}, source[property]);
} else {
target[property] = source[property];
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Tests Failed

To view the Playwright test report locally, run:

REPORT_DIR=$(mktemp -d) && gh run download 28927440502 -n playwright-report -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR"

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e949df782

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ghost/admin/package.json
Comment thread .github/workflows/ci.yml
Comment thread compose.dev.yaml
Comment thread koenig/koenig-lexical/eslint.config.mjs Outdated
Comment thread .github/workflows/publish-koenig-package.yml Outdated
"@tryghost/string": "0.3.5",
"@tryghost/url-utils": "5.2.7",
"handlebars": "4.7.9",
"juice": "12.1.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Publish the same Juice dependency Ghost ships

@tryghost/kg-default-cards now declares juice@12.1.1, but the root workspace overrides juice to 9.1.0 and the Ghost archive copies that override, so CI/Ghost build and ship this card package against 9.1.0 while the standalone npm package will install 12.1.1 for external consumers. That breaks the stated “content that shipped inside a released Ghost” guarantee for the Koenig npm packages; align this dependency with the override or remove the override for this package before publishing it separately.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed real, but pre-existing rather than introduced here: Ghost's root workspace has overridden juice to 9.1.0 since before this merge, so the npm-installed kg-default-cards@12.1.1-juice was already being forced to 9.1.0 inside Ghost while external consumers got 12.1.1. The merge preserves that status quo (and the shipped archive matches what CI tests). Needs a team decision: either align kg-default-cards to juice 9.1.0 (changes the external npm package) or drop/scoped-narrow the root override. Leaving this thread open.

Comment thread .github/workflows/ci.yml
@kevinansfield
kevinansfield force-pushed the koenig-monorepo-merge branch from 10a6308 to e6ebed0 Compare July 8, 2026 08:55
kevinansfield added a commit that referenced this pull request Jul 8, 2026
ref #29171

The "Unit tests" job wedged until cancelled: every suite passed but the
job never finished. nx prints a task's output only on completion, and
the one task that never completed (twice in a row) was
kg-default-nodes:test:unit.

Reproduced in a Linux container with the exact PR tree: direct
`pnpm test:unit` exits cleanly, but `nx run` of the same target prints
"708 passing" and then hangs forever. nx runs tasks with socketpair
stdio, and in that environment the @prettier/sync worker channel (a
MessagePort from make-synchronized) stays referenced after the tests
finish - mocha waits for the event loop to drain, so the process never
exits. kg-default-nodes is the only mocha-based koenig package whose
tests use @prettier/sync, which is why its nine sibling packages with
the identical c8+mocha+tsx setup were unaffected.

- added mocha --exit so the process exits once the run completes;
  coverage collection is unaffected (verified 91% lines in-container)
- bounded each unit-test retry attempt with `timeout 25m` so a future
  exit-hang becomes a retriable failure (nx skips already-passed
  projects on retry) instead of wedging the job for 6 hours
- gave the legacy tests step timeout-minutes: 30 - the sqlite leg hit a
  similar one-off vitest teardown hang that held the job for 90 minutes
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.29%. Comparing base (657f1f3) to head (df3249f).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #29171      +/-   ##
==========================================
+ Coverage   74.28%   74.29%   +0.01%     
==========================================
  Files        1566     1566              
  Lines      135733   135781      +48     
  Branches    16443    16463      +20     
==========================================
+ Hits       100828   100884      +56     
+ Misses      33873    33865       -8     
  Partials     1032     1032              
Flag Coverage Δ
e2e-tests 76.45% <ø> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ref #29171

Converted the imported koenig/* packages to pnpm workspace members:
consumers reference them as workspace:*, koenig inter-package deps use
workspace:~ (the publish model computes patch versions from npm, so
package.json digits go stale), scripts moved from yarn to pnpm, and
shared dev deps route through the catalog.

Also wired the nx task graph so test targets work in the monorepo:

- ghost/core's plain test:e2e/test:integration/test:legacy targets get
  ^build like their test:ci:* variants, and the build targetDefaults
  outputs include {projectRoot}/build - the kg packages emit build/
  (dual esm/cjs tsc), so without it nx cache restores produced empty
  packages and ghost/core tests failed with MODULE_NOT_FOUND on
  @tryghost/kg-converters
- ghost/admin's dev/build/test targets depend on ^build so its
  workspace deps (koenig-lexical, kg-converters, ...) are built first
- kg-default-nodes' mocha runs with --exit: under nx's task runner
  (socketpair stdio) the @prettier/sync worker channel stays referenced
  after the suites finish, so mocha - which waits for the event loop to
  drain - never exited and wedged CI. It is the only mocha-based koenig
  package using @prettier/sync; direct pnpm runs were unaffected.
ref #29171

Wired the imported koenig/* packages into the Ghost CI matrix and the
release lane:

- unit/lint/acceptance coverage for the koenig packages in ci.yml; the
  Playwright acceptance matrix is selected via an nx "playwright" tag
  on the packages instead of a hardcoded list
- the koenig-lexical acceptance leg installs MS core fonts (caret
  position assertions depend on Arial line-wrap metrics, not just
  screenshots) and firefox media codecs via playwright install-deps;
  scoped to that one matrix leg because repo-wide apt-get has a
  history of hangs
- npm publishing runs only in the release tag lane
  (publish_koenig_packages, after publish_ghost) and skips prerelease
  tags since the publish script computes stable versions; failures
  feed notify_release_failure. publish-koenig-package.yml remains as a
  workflow_dispatch escape hatch for out-of-band single-package
  publishes, with dispatch inputs passed via env rather than
  interpolation
- each unit-test retry attempt is bounded by `timeout 25m` so a test
  process that finishes but never exits becomes a retriable failure
  (nx skips already-passed projects on retry) instead of wedging the
  job for 6 hours; the legacy step gets timeout-minutes for the same
  reason
- replaces the pages.yml workflow from the archived Koenig repo: builds the koenig-lexical demo and deploys it to GitHub Pages with the koenig.ghost.org CNAME on main pushes touching koenig/
- Pages needs enabling on this repo (gh-pages branch) and the TENOR_API_KEY / KLIPY_API_KEY secrets copying over before the old repo is archived
- component discovery now walks workspace: deps transitively, since the kg-* packages depend on each other (previously only direct file: deps of ghost/core were packed)
- components are packed from the source workspace so pnpm rewrites workspace: specs itself; packing the deploy-dir copies fails on the workspace protocol
- every component gets a pnpm override pinning it to its bundled tarball, so nested specs like kg-html-to-lexical's ~2.1.3 on kg-default-nodes resolve to the tarball that shipped in the archive instead of the npm registry — production installs of Ghost never depend on Koenig packages being published
ref #29171

Updated the koenig/* READMEs and agent docs for their new home in the
Ghost monorepo, and brought the imported code up to Ghost's lint
conventions:

- koenig-lexical's five warn-level eslint rules are now errors per the
  repo-wide "error or off, never warn" rule; pre-existing
  react-hooks/exhaustive-deps violations carry inline disables with
  rationale comments (GifSelector re-subscribes its keydown handler
  every render; EmbedCard's observer effect intentionally runs once)
- removed an unused import left behind by a commented-out test
- kg-default-nodes lint fixes that Koenig CI never caught because its
  lint was not wired into a posttest there
ref #29171

The kg server packages are now built before the dev containers start
(docker:up depends on their build targets, so a fresh checkout works
without a manual build step), and pnpm dev:lexical runs the in-repo
Koenig editor instead of expecting a dev server in an external Koenig
checkout:

- a dev:integrated script in koenig-lexical rebuilds the editor on
  change and serves its dist via vite preview, alongside watchers for
  kg-default-nodes and kg-default-transforms
- the docker:dev:lexical nx target starts that watcher with the rest
  of the dev stack; the Caddy dev gateway proxies
  /ghost/assets/koenig-lexical/* to it so Admin loads the local build
- dev-gateway docs updated to match (note: the Caddyfile comment
  deliberately avoids backticks - Caddy's lexer treats them as quote
  delimiters even inside comments)
@kevinansfield
kevinansfield force-pushed the koenig-monorepo-merge branch from 407ae32 to df3249f Compare July 8, 2026 11:47
@kevinansfield
kevinansfield merged commit bc45ce2 into main Jul 8, 2026
49 of 50 checks passed
@kevinansfield
kevinansfield deleted the koenig-monorepo-merge branch July 8, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants