Skip to content

Register extension-mermaid as the sixth family package #527

Closed

Description

@HMarzban

Part of #521. Depends on #526. Read the tracker first: its §Shared contract binds this issue. Work on main.

Summary

Run the package-local gates and the CJS gate, then register the sixth package in every family list, CI file, Docker file and doc count. Nothing here changes package source.

Rulings: 8, 12 (#521 §Maintainer rulings). Must land before #528: the Dockerfile lines must exist before the webapp imports the package.

Current behaviour

  • scripts/publishable-extensions.ts:3-9 is the single list that most gates read (read from code). Several files still hard-code the five packages. They are the CI filter, the prod workflow matrix, three Dockerfiles, the dev compose file, and many "five" counts in docs and skills (read from code).

Files

Files

  • Modify: scripts/publishable-extensions.ts, scripts/run-tests.sh:25, .github/filters/extensions.yaml, .github/workflows/prod.docs.plus.yml, .github/workflows/stage.docs.plus.yml:129, .github/actions/build-extensions/action.yml:7,19, .github/dependabot.yml.
  • Modify: apps/webapp/docker/Dockerfile.bun (6 lines), apps/hocuspocus.server/docker/Dockerfile.bun (1), apps/admin-dashboard/docker/Dockerfile.bun (1), apps/webapp/docker/docker-compose.dev.yml (1).
  • Modify: AGENTS.md, RELEASE_POLICY.md, README.md, extensions/README.md, context7.json, CONTRIBUTING.md, docs/README.md, both copies of the release-extensions and release-product skills (.cursor/skills/ and .agents/skills/), .claude/workflows/release-product.js.
  • Not touched: backend-ci.yml, release-family.ts, check-ci.ts, extension-preflight.sh, build-extensions.sh, lockstep-guard.yml (each reads the SSOT, a glob, or never builds mermaid), and the root CHANGELOG.md (release time).

Implementation steps

  • Step 1: Run the package-local gates.

    • In PKG: bun run build, bun run typecheck, bun run test and bun run prepublishOnly. Each exits 0; test exits 0 with All specs passed! in its output.
    • The d.ts greps ([Tracking] Mermaid diagrams in docs.plus through a headless Pele extension #521 §Global constraints → Pele).
    • In PKG: bun pm pack --dry-run. The list holds package.json, README.md, CHANGELOG.md and the seven dist/ files, and no assets/, docs/, examples/, cypress/, test/ or src/. LICENSE appears only when the dry run runs prepack; record which. Record the size.
    • From REPO: bun scripts/check-quickstart-example.ts extension-mermaid prints in sync. Then the Root checks.
  • Step 2: Run the CJS gate (its home).

    • Run grep -n "pele/lazy" PKG/dist/index.cjs and record the emitted form.
    • Set NODE to the lowest installed Node binary that is 20 or later (on the maintainer laptop, ~/.nvm/versions/node/v22.23.3/bin/node), and record $NODE --version.
    • In PKG: for a native import("pele/lazy"), run $NODE -e "import('pele/lazy').then(() => console.log('ok'))". A require("pele/lazy") inside any wrapper, such as __toESM(require("pele/lazy")), takes the require branch: run $NODE -e "require('pele/lazy'); console.log('ok')".
    • In both branches, also run $NODE -e "require('./dist/index.cjs'); console.log('ok')" in PKG.
    • ok is pass. Anything else is fail, but read the error first: a missing DOM global at load time is a different finding from an ESM error.
    • A Node 20.19 run is owed when no Node 20 is installed. Install nothing.
  • Step 3: Add the SSOT entry. Append { dir: 'extension-mermaid', hasUnit: false } after the placeholder entry in scripts/publishable-extensions.ts. Run bun scripts/publishable-extensions.ts --only extension-mermaid --gates. Expected: extensions/extension-mermaid 0 @docs.plus/extension-mermaid (clean-room Cypress).

  • Step 4: Run the EXT_ONLY gates. Stop any playground on ports 5173-5178 first.

    • EXT_ONLY=extension-mermaid bash scripts/extension-preflight.sh exits 0, and prints preflight @docs.plus/extension-mermaid and quickstart example: in sync for extension-mermaid.
    • EXT_ONLY=extension-mermaid bash scripts/run-tests.sh --extensions exits 0, with Extension gates: PASSED.
  • Step 5: Wire CI.

    • .github/filters/extensions.yaml: after the placeholder block, add extension-mermaid: with - *shared and - 'extensions/extension-mermaid/**'.
    • .github/workflows/prod.docs.plus.yml: add R_MERMAID: ${{ steps.filter.outputs.extension-mermaid }} after R_PLACEHOLDER, add ,"extension-mermaid" after "extension-placeholder" in the all= JSON, and add [ "${R_MERMAID}" = "true" ] && sel+=('"extension-mermaid"') after the placeholder sel+= line.
    • .github/dependabot.yml: in the bun ignore: list, after - dependency-name: 'linkedom' (line 44), add the comment # pele: bump by hand; rerun the render measure, the security probe rows, and check that Pele made no breaking change. and then - dependency-name: 'pele'.
    • Check: grep -c extension-mermaid .github/filters/extensions.yaml .github/workflows/prod.docs.plus.yml prints 2 and 3 (the filter names the package twice); grep -c "dependency-name: 'pele'" .github/dependabot.yml prints 1.
  • Step 6: Update Docker. After each line that names extension-placeholder in the three Dockerfiles, add a copy with extension-mermaid. In docker-compose.dev.yml, add - ../../extensions/extension-mermaid:/app/extensions/extension-mermaid after the inline-code mount. Check: grep -c extension-mermaid prints 6, 1, 1 and 1 for the four files.

  • Step 7: Add the table rows (alphabetical).

    • extensions/README.md "Choose an extension": | [`extension-mermaid`](./extension-mermaid/) | Draws each `mermaid` code block as a diagram under its source, and the document stores only the source. |
    • extensions/README.md CSS-export table: | [`extension-mermaid`](./extension-mermaid/) | Mermaid diagram preview for `codeBlock`, drawn by Pele | `./styles.css` | 5178 |
    • README.md extensions table: | [`extension-mermaid`](extensions/extension-mermaid/) | Mermaid diagram preview for `codeBlock`, drawn by Pele |
    • RELEASE_POLICY.md, the package bullet list: - `@docs.plus/extension-mermaid`.
    • Check: grep -c extension-mermaid extensions/README.md README.md RELEASE_POLICY.md prints at least 2, 1 and 1.
    • AGENTS.md run order: insert 6. `@docs.plus/extension-mermaid` — clean-room Cypress against built `dist/`. and renumber the webapp Jest item to 7.
  • Step 8: Update the counts. Anchor on text, not line numbers.

    • The rule. Where a sentence counts the publishable extensions, change "five" to "six", "Five" to "Six", and "5" to "6" (and five-tuple → six-tuple, five-package → six-package, 4× → 5× in RELEASE_POLICY's typing-burden line). Files: prod.docs.plus.yml (3 places), stage.docs.plus.yml, build-extensions/action.yml (2), AGENTS.md (2), RELEASE_POLICY.md, README.md, extensions/README.md, CONTRIBUTING.md (3), docs/README.md, both release skills, release-product.js (2).
    • Keep "five" in history. RELEASE_POLICY.md line 12 (the Phase 1 table row), lines 59-60 (the deleted Releases and "The five git tags stay"), 83, 85, 102, 120 and 125 (Phase 1 and Trigger D); "all five shipped 2.0.0 independently" in both release-extensions copies; the AGENTS.md "209 s for all five" timing; the README Traefik hostnames line; and the prod "five-service" roll lines.
    • Change in RELEASE_POLICY.md (read at the pinned commit): lines 9, 11, 17, 65, 73, 77 (five-tuple), 135 (five-package), 176-178, 268 ("applies to all five"), 290 ("The five per-package tags"), 294 ("Five releases means five Discord embeds") and the 4× typing-burden line.
    • Real rewrites:
    File Find Replace with
    scripts/run-tests.sh:25 (5173-5177) (5173-5178)
    AGENTS.md ports line placeholder 5177. placeholder 5177, mermaid 5178.
    RELEASE_POLICY.md readiness Before any extension ships its `2.0.0` (and joins the lockstep family), it needs Before any extension first publishes, it needs
    RELEASE_POLICY.md readiness the whole line - [ ] `[2.0.0]` `CHANGELOG.md` entry following the [style guide](#changelog-style-guide) - [ ] A CHANGELOG.md entry for the first version it publishes, following the [style guide](#changelog-style-guide)
    RELEASE_POLICY.md hypermultimedia / inline-code / placeholder: hypermultimedia / inline-code / mermaid / placeholder:
    README.md All five are published on npm and share one version, released together. All six share one version and release together. `extension-mermaid` is not on npm yet; it publishes with the next family release.
    extensions/README.md:3 Five publishable Tiptap extensions for [docs.plus](https://docs.plus). The five packages share one version under the `@docs.plus` npm scope, and they release together. Six publishable Tiptap extensions for [docs.plus](https://docs.plus). The six packages share one version under the `@docs.plus` npm scope, and they release together. `extension-mermaid` is not on npm yet; it publishes with the next family release.
    extensions/README.md deps installs `@floating-ui/dom`. The other three … None of the five declares a Node or Bun engine floor. installs `@floating-ui/dom`. `extension-mermaid` installs `pele`, which declares Node 20 or later. The other three … None of the six packages declares its own Node or Bun engine floor.
    extensions/README.md CSS Two packages ship a stylesheet and the two-name list Three packages ship a stylesheet, adding @docs.plus/extension-mermaid/styles.css
    extensions/README.md keys extension-placeholder` binds no key, so it carries no such table. `extension-mermaid` and `extension-placeholder` bind no key, so they carry no such table.
    extensions/README.md CONTRIBUTING links the inline-code link add [mermaid](./extension-mermaid/CONTRIBUTING.md)
    docs/README.md The five Tiptap extensions docs.plus publishes to npm The six `@docs.plus/extension-*` Tiptap extensions
    context7.json:6 Ships 5 Tiptap 3 extensions: hyperlink, hypermultimedia, indent, inline-code, placeholder. Ships 6 Tiptap 3 extensions: hyperlink, hypermultimedia, indent, inline-code, mermaid, placeholder.
    context7.json:30 The five: …, extension-placeholder. The six: …, extension-mermaid, extension-placeholder. extension-mermaid is not on npm yet; it publishes with the next family release.
    • context7.json: after the hypermultimedia stylesheet rule, add one rule: "With extension-mermaid, import @docs.plus/extension-mermaid/styles.css. Without it, Pele's own error text shows and the diagram dims while the source has a mistake. A host addNodeView for codeBlock, or an earlier plugin that sets nodeViews.codeBlock, replaces the diagram view with no error."
    • On a CJS fail only: after the RELEASE_POLICY paragraph that starts "The extension-hyperlink package is the reference shape", add: **ESM-only exception — `@docs.plus/extension-mermaid`.** Its `dist/index.cjs` cannot load `pele/lazy` on Node <version>, because `pele` ships ESM only. Load the package with `import` or a bundler. Recorded <date>.
  • Step 9: Format and sync. Run bunx prettier --write --ignore-unknown on every file this task touched. Then copy each .cursor/skills/<skill>/SKILL.md to its .agents/skills/ twin (.prettierignore skips .agents/skills), and cmp each pair. Expected: no output.

  • Step 10: Check for leftovers.

    • git -C REPO grep -n -i -w -e five -e 'all 5' -e 'ships 5' over the files in Step 8 prints only the history lines that Step 8 keeps.
    • for f in $(git -C REPO grep -l extension-placeholder -- ':!bun.lock' ':!extensions/extension-placeholder'); do grep -q extension-mermaid "REPO/$f" || echo "$f"; done prints exactly: CHANGELOG.md, apps/webapp/package.json, apps/webapp/src/components/TipTap/CLAUDE.md, apps/webapp/src/components/TipTap/TipTap.tsx, apps/webapp/src/components/TipTap/placeholders/buildBreadcrumbPlaceholder.test.ts and apps/webapp/src/components/TipTap/placeholders/buildBreadcrumbPlaceholder.ts. After Draw Mermaid diagrams in the pad, history and /editor #528, apps/webapp/package.json and TipTap.tsx drop off this list; the other four stay, because none of them ever names the package.
  • Step 11: Run bun run check:agent-docs and the Root checks. Each exits 0.

  • Step 12: Review checkpoint. Report the Step 1 gates, the pack list and size, the CJS verdict with its Node version, and the Step 4 and Step 11 results.


Acceptance criteria

  • The package-local gates and the EXT_ONLY gates pass, and the pack list holds only the expected files.
  • The CJS verdict is pass, or RELEASE_POLICY.md holds the ESM-only exception.
  • The Step 10 leftover checks print exactly their expected lists.
  • bun run check:agent-docs and the Root checks pass.

Activity

  1. HMarzban commented on Oct 19, 2026

    @HMarzban
    CollaboratorAuthor

    Step 2 CJS gate, progress 2026-10-19

    • The built dist/index.cjs loads pele/lazy through a native import() inside a lazy function, so the import branch is the gate.
    • On Node 22.23.3:
      • import('pele/lazy') passes.
      • require('./dist/index.cjs') loads with no DOM global.
      • require('pele/lazy') also passes, but only because Node 22 can require an ES module.
    • Still owed: the run on Node 20.19 itself. It is not installed on this machine, and Step 2 says to install nothing. The card stays open until that run passes.
  2. HMarzban commented on Oct 19, 2026

    @HMarzban
    CollaboratorAuthor

    Step 2 CJS gate on Node 20.19: pass (2026-10-19)

    Node v20.19.6, installed with nvm install 20.19, was run by full path. The default Node is unchanged.

    Check Result
    node -e "import('pele/lazy').then(() => console.log('ok'))" in the package ok, exit 0
    node -e "require('./dist/index.cjs')" ok, exit 0: loads with no DOM global and exports Mermaid
    Emitted form in dist/index.cjs import("pele/lazy") inside a lazy function, so Pele loads only on first draw

    The other steps were already met. The SSOT entry and the CI wiring are done: tonight's CI/CD run 39297468969 ran Ext (extension-mermaid) and passed. The Docker images built and deployed in the same run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions