From b86596b0427133d9485b199b9105de398c87d413 Mon Sep 17 00:00:00 2001 From: Nick Gomez <122398915+nick-inkeep@users.noreply.github.com> Date: Wed, 1 Jul 2026 10:41:35 -0700 Subject: [PATCH] Extract OpenKnowledge marketing site into a private ok-marketing app (#2334) * docs(open-knowledge): add marketing-site-separation spec PRD plus technical spec for extracting the marketing site into its own private, non-mirrored Next.js app (private/ok-marketing), leaving docs and the product routes public and preserving every current URL via Vercel Microfrontends. Covers the vendored-core editor-preview mechanism (committed dist plus a CI drift-guard), the component untangle, the cutover and rollback plan, and the verification substrate. Includes the decision log, spec-local evidence, and two cold-reader audits. Internal only; specs/ is not mirrored to the public repo. * [US-002] scaffold private/ok-marketing Next.js app + workspace member * [US-003] vendor core dist behind a shim with a rebuild-and-diff drift guard Give the marketing app the live editor preview's core slice without crossing the pnpm/Bun boundary at build time. Commit core's built barrel (dist/index.mjs plus its hashed sibling chunk) under private/ok-marketing/vendor/open-knowledge-core/ behind a thin shim package.json that re-exports it and mirrors core's dependency block, and consume it via a file: dep. This is the raw committed-dist path the US-001 spike certified, not the ok-editor-preview wrapper fallback. scripts/verify-core-dist.mjs rebuilds core with Bun and diffs its fresh dist closure against the committed copy, failing with the regenerate command on drift; --write (regen-core-dist) refreshes it. The closure is resolved from index.mjs's own local imports, so a content-hash rename of the shared chunk is caught rather than assumed away. The drift classifier is unit tested. Supporting wiring: - .gitignore exempts the vendored dist from the dist/ build-output rule - biome files.includes and tsconfig exclude vendor/ so the formatter and typechecker skip the minified barrel and the tiptap-typed .d.ts - carve private/ok-marketing/vendor out of the dep-drift and workspace-membership trap scans, since the shim's mirrored dep block is a vendored artifact, not a workspace member Also reconcile the shared-dep drift the US-002 scaffold introduced but did not check: align next to ^16.2.4 to match the rest of the monorepo, and grandfather the remaining heterogeneous frontend devDeps alongside copilot-app in the drift allowlist. Monorepo traps and lockfiles are green. * [US-004] untangle (home)-coupled components out of the docs app Move footer, dot-texture, and marketing-button out of the docs app's (home) route group into neutral src/components/ so the staying routes (/continue, /d/[encoded]) no longer reach into (home). All eight importers repointed to the @/components/* alias. No file outside (home) imports from (home) anymore; docs build and typecheck stay green. * [US-005] relocate marketing landing + shared chrome into ok-marketing Copy the (home) landing closure out of the docs app into the private marketing app with the directory structure preserved so @/ aliases resolve, replacing the docs-coupled pieces: - getGitHubStars: direct GitHub REST fetch in lib/github-stars.ts (no core import), returning null on failure at the network trust boundary. - hero: static, self-contained preview. The chat intro animation is kept verbatim; the live TipTap editor pane is replaced by a step-driven static document plus an inline activity chart. The live editor lands in US-006. - provider: next-themes forced-light, dropping the fumadocs RootProvider. - global.css: self-contained (no fumadocs imports), class-based dark variant, fd-background and fd-muted-foreground registered as theme tokens. - next.config: PostHog /ingest rewrites; instrumentation-client copied. Duplicates the shared presentational set, replicates the root layout, fonts, JsonLd and PostHog wiring, and copies the referenced public assets. New deps are aligned to existing scanned versions to keep dependency drift minimal. * [US-006] wire the live OK editor preview in ok-marketing via vendored core Bring the ok-editor closure and the two ui components it needs into the marketing app, and restore the live hero-preview so the hero mounts the real TipTap editor instead of the static placeholder. The editor imports its four client symbols (MarkdownManager, sharedExtensions, CodeBlockFidelity, PREVIEW_THEME_TOKENS) from the vendored core shim. Add the TipTap and CodeMirror runtime deps at the versions the docs app uses so they dedupe to a single @tiptap instance shared with the shim. The vendored shim exposes only four symbols, so the extension packages' command-type augmentations are loaded via a devDependency-backed ambient declaration. Client bundle carries the editor pipeline with zero node: builtins; core source and exports are unchanged. * [US-007] drop docs (home) root, migrate middleware to proxy Docs no longer answers /; the marketing landing now lives in the private marketing app. Remove the (home) route group and its orphaned exclusive dependencies (the ok-editor live-preview closure, ok-icon, ui/sheet, ui/tooltip) so the public docs no longer carries the editor-to-core coupling that the separation moves to the private app. Rename middleware.ts to proxy.ts (Next 16), keeping the www to apex 308 canonicalization and the /.well-known/* carve-out that serves AASA as a direct 200 on both apex and www. Verified against next 16.2.3 that the config export stays named config. Simplify provider.tsx (drop the dead /-only light theme pin) and make the sitemap docs-only (drop the root entry so the public standalone deploy does not advertise a 404 root). Document the /docs default route in a mirror-safe next.config.ts comment. * [US-008] wire Vercel Microfrontends config (docs default, marketing child) Compose openknowledge.ai from two Vercel projects via Vercel Microfrontends, config only. The docs app stays the default (apex + every current path); the marketing app is a child claiming only / plus its asset prefix. - add @vercel/microfrontends to both apps; wrap both next.configs with withMicrofrontends - microfrontends.json in the docs (default) app: docs=default (no routing), marketing=child routing / and /marketing-assets/:path* - move marketing public/ assets under /marketing-assets so they route to the marketing zone (the docs app still serves /images/* and /ok-logo.png, so a shared root path would hijack docs assets on the apex) - duplicate HSTS (includeSubDomains; preload) in the marketing next.config - MICROFRONTENDS.md documents the topology, Fallback Environment=Production intent, the app-name-must-match-Vercel-project check, and that the production apex cutover is a separate human step (not executed here) - contract test pins the marketing routing entry against the app's real package name and public assets The docs app builds green off-Vercel with the wrapper and config present, so the public mirror's standalone docs build is unaffected. * [US-009] point marketing subscribe form at the apex /api/subscribe cross-origin Extract the newsletter network contract into lib/subscribe.ts: a single-source subscribeSchema, an absolute apex SUBSCRIBE_ENDPOINT (derived from SITE_URL, env-overridable for local dev), and subscribeToNewsletter(). The marketing zone has no /api route, so the form must POST cross-origin to the product app's endpoint (which already serves wildcard CORS + an OPTIONS preflight for exactly this caller) rather than a relative path that would 404. Pin the cross-app request contract in subscribe.test.ts: endpoint is absolute apex + cross-origin, the POST sends a JSON { email } body that parses under a mirror of the docs route schema, and a non-ok response maps to { ok: false }. * [US-010] add ok-marketing CI validation gate + verify-core-dist wiring Add .github/workflows/ok-marketing-validation.yml validating the private marketing app on changes. A thin caller of the reusable _subtree-validation.yml runs the standard build/lint/typecheck/test matrix (copilot-app precedent, composite install, marketing-scoped paths). A bespoke verify-core-dist job the reusable cannot express sets up Node plus Bun, installs the Open Knowledge workspace, and runs the rebuild-and-diff drift guard so a stale vendored core dist fails CI with the regenerate command. The gate aggregator tolerates cancelled/skipped and keeps abandoned fail-closed (passes check:gate-cancel-resilient). The drift guard fires on marketing paths only, not core source: it rebuilds current core on every marketing PR so a since-moved core surfaces the moment marketing is touched, without coupling every core change to the marketing vendor. Registering it as a required check in the branch-protection ruleset is a follow-up repo-admin step, noted in the workflow header. * [US-011] add pre-cutover URL/AASA/HSTS sweep + render smoke + cutover runbook * fix(ci): harden ok-marketing drift-guard + prune dead editor deps Phase 7 no-skimp fixes from the adversarial review gate. verify-core-dist gate (ok-marketing-validation.yml): - single-source the path scope via a paths job consumed by both the matrix caller and the drift gate, so the two cannot silently diverge - the drift gate now also fires on public/open-knowledge/packages/core changes, so a core-source edit re-runs the rebuild-and-diff on the same PR that drifts the vendored dist (genuinely fail-closed) - the aggregate gate now includes detect-core-dist-changes in needs and fails closed on its failure; a transient path-detect failure previously skipped the guard while the required gate stayed green marketing: - delete the dead download-links.ts resolver fork; fold the two consumed constants (DMG_ASSET_NAME, STABLE_DMG_URL) into site.ts - add vendored-core-contract.test.ts: runs the real vendored .mjs against the hand-authored .d.ts so a core signature change cannot leave the types stale docs: - remove 11 tiptap/codemirror deps + @floating-ui/dom, unused since the (home) editor was removed; they were mirroring to the public repo and reintroducing the editor-dep surface the separation exists to shed * chore(mirror): exclude docs/microfrontends.json from the public mirror docs/microfrontends.json names the private @inkeep/ok-marketing app and its routes. openknowledge.ai deploys from agents-private (confirmed: the open-knowledge-docs Vercel project Root Directory is public/open-knowledge/docs), so the public mirror is not a Vercel deploy source and the file is inert there. Excluding it keeps the OSS repo from disclosing an internal app name and route while the private composed deploy keeps the file unchanged. The withMicrofrontends wrapper and the @vercel/microfrontends dependency stay public (harmless and inert in the public standalone docs build). * fix(boundaries): exclude vendored re-export shims from the private-package name map The vendored core shim (private/ok-marketing/vendor/open-knowledge-core) re-uses the public package name @inkeep/open-knowledge-core so the private marketing app can consume it via a file: dependency. check:boundaries keyed its private-package map by name and walked all of private/, so the shim registered that public name as private-only and both scans (public source imports + public workspace: manifests) misresolved the OK app's legitimate public-core references to the private shim. Skip vendor/ dirs the same way node_modules is skipped: committed dependency output, not first-party private source. * chore(docs): shed orphaned (home)-landing code after the marketing separation US-007 dropped the docs (home) landing; these were its private supporting code, now unused in docs (0 importers, verified by knip) and already relocated to private/ok-marketing: - use-is-in-view / use-prefers-reduced-motion scroll hooks (deleted) - CodexBrandIcon / CodexBrandMonoIcon (plain CodexIcon stays; the now-unused useId import drops with them) - EXAMPLE_KB_SHARE_URL share-splash constant Completes the separation's goal of shedding the landing footprint from the public-mirrored docs app, the source-level analog of the dead editor-dep removal. check:drift (knip) and docs typecheck are green. * fix(ci): make vendored dist + mirror docs build survive the main merge - verify-core-dist: regenerate the vendored core dist. The merge pulled main's core changes, so the committed vendored index.mjs was stale vs a fresh build. - mirror-runnability (required check): the materialized mirror docs build threw MicrofrontendsError because withMicrofrontends() needs a microfrontends.json, which the mirror-exclude removes. Guard the wrapper behind an existsSync check so the public standalone docs build is a plain Next.js app, while agents-private (which keeps the config) still gets Microfrontends. Confirmed locally via check:ok-mirror-runnable (materialized export builds clean). * fix(ok-marketing): address review findings (JSON-LD, subscribe timeout, DRY) - layout.tsx: drop the copy-pasted alternateName 'OpenKnowledge Docs' from the marketing WebSite JSON-LD (factually wrong for the apex; SITE_NAME already names it). - subscribe.ts: add AbortSignal.timeout(10s) to the cross-origin subscribe POST so a hung docs zone cannot lock the form's submit state forever. - footer.tsx: import GITHUB_URL/DISCORD_URL/X_URL from site.ts instead of re-hardcoding them (site.ts is the single source; the merge added those exports). - url-continuity-sweep.mjs: add .catch() so a throw mid-sweep fails loud with a non-zero exit instead of an unhandled rejection (pre-cutover safety gate). - instrumentation-client.ts: document why the PostHog defaults date stays '2025-11-30' (posthog-js is override-pinned to 1.316.1 here; docs is a separate Bun workspace). * chore(ok-marketing): address review pending-recommendations - lint-staged + check-pre-push SUBTREES: register private/ok-marketing so staged files route to its Biome formatter and the scoped pre-push runs its checks (every peer subtree already had both entries). - site.ts: document the DMG_ASSET_NAME lockstep with the docs download-links.ts canonical source (duplicated, not imported, across the workspace boundary). - AGENTS.md + CI.md: enumerate the new private/ok-marketing subtree and its OK Marketing Validation workflow (AGENTS.md kept under the 38,500-byte guard). - site.test.ts + subscribe.test.ts: cover metaDescription's four branches, the SUBSCRIBE_ENDPOINT env override, and the abort-signal on the fetch. * fix(ok-marketing): restore the Brand link in the marketing footer Visual QA against prod caught that the relocated footer dropped the /brand link: prod shows Brand, Terms of Service, Privacy; the marketing footer had only Terms and Privacy. Add it back with the same internal/external handling as the docs footer. /brand is served by the docs zone and Vercel Microfrontends routes it there, so it stays a same-tab in-product link. * test(check-pre-push): pin ok-marketing in the SUBTREES expected set Follow-on to registering private/ok-marketing in check-pre-push.mjs SUBTREES: the 'SUBTREES contains the expected set' guard hardcodes the full list to catch accidental additions/removals, so it must list ok-marketing too. (The pre-push guard correctly flagged the omission.) --------- GitOrigin-RevId: b0f3669926d09339e1a09b7983e20cef8dac2ea3 --- bun.lock | 49 +- docs/next.config.ts | 17 +- docs/package.json | 13 +- docs/src/app/(home)/brand/page.tsx | 6 +- docs/src/app/(home)/feature-item.tsx | 25 - docs/src/app/(home)/layout.tsx | 12 - docs/src/app/(home)/page.tsx | 50 -- docs/src/app/(home)/section.tsx | 13 - .../(home)/sections/agent-brain-graphic.tsx | 133 ---- .../app/(home)/sections/call-to-action.tsx | 126 ---- .../src/app/(home)/sections/collaboration.tsx | 241 ------ .../app/(home)/sections/eng-specs-graphic.tsx | 241 ------ docs/src/app/(home)/sections/hero-preview.tsx | 691 ------------------ docs/src/app/(home)/sections/hero.tsx | 136 ---- .../sections/knowledge-base-graphic.tsx | 248 ------- .../sections/made-for-agents-preview.tsx | 303 -------- .../app/(home)/sections/made-for-agents.tsx | 89 --- .../(home)/sections/own-your-knowledge.tsx | 45 -- .../app/(home)/sections/put-it-to-work.tsx | 54 -- docs/src/app/(home)/sections/rich-editing.tsx | 625 ---------------- docs/src/app/(home)/site-nav.tsx | 299 -------- .../src/app/d/[encoded]/splash-share-view.tsx | 4 +- docs/src/app/provider.tsx | 7 - .../(home) => components}/dot-texture.tsx | 0 .../src/{app/(home) => components}/footer.tsx | 0 docs/src/components/icons/codex.tsx | 59 +- docs/src/components/logo-context-menu.tsx | 70 -- .../marketing-button.tsx | 0 .../ok-editor/block-type-selector.tsx | 140 ---- docs/src/components/ok-editor/bubble-menu.tsx | 169 ----- docs/src/components/ok-editor/drag-handle.tsx | 99 --- docs/src/components/ok-editor/mode-toggle.tsx | 54 -- docs/src/components/ok-editor/ok-editor.css | 538 -------------- docs/src/components/ok-editor/ok-editor.tsx | 175 ----- .../ok-editor/preview-code-block.tsx | 90 --- docs/src/components/ok-editor/seed.ts | 64 -- .../components/ok-editor/slash-command.tsx | 134 ---- docs/src/components/ok-editor/slash-items.tsx | 136 ---- docs/src/components/ok-editor/slash-menu.tsx | 45 -- .../components/ok-editor/source-editor.tsx | 63 -- docs/src/components/ok-icon.tsx | 61 -- .../(home) => components}/section-heading.tsx | 0 docs/src/components/slide-page.tsx | 4 +- docs/src/components/subscribe-form.tsx | 2 +- docs/src/components/ui/context-menu.tsx | 104 --- docs/src/components/ui/sheet.tsx | 134 ---- docs/src/components/ui/tooltip.tsx | 53 -- docs/src/lib/brand-assets.ts | 2 - docs/src/lib/copy-svg.ts | 5 - docs/src/lib/site.ts | 3 - docs/src/lib/use-is-in-view.ts | 19 - docs/src/lib/use-prefers-reduced-motion.ts | 15 - .../src/{middleware.test.ts => proxy.test.ts} | 6 +- docs/src/{middleware.ts => proxy.ts} | 2 +- 54 files changed, 63 insertions(+), 5610 deletions(-) delete mode 100644 docs/src/app/(home)/feature-item.tsx delete mode 100644 docs/src/app/(home)/layout.tsx delete mode 100644 docs/src/app/(home)/page.tsx delete mode 100644 docs/src/app/(home)/section.tsx delete mode 100644 docs/src/app/(home)/sections/agent-brain-graphic.tsx delete mode 100644 docs/src/app/(home)/sections/call-to-action.tsx delete mode 100644 docs/src/app/(home)/sections/collaboration.tsx delete mode 100644 docs/src/app/(home)/sections/eng-specs-graphic.tsx delete mode 100644 docs/src/app/(home)/sections/hero-preview.tsx delete mode 100644 docs/src/app/(home)/sections/hero.tsx delete mode 100644 docs/src/app/(home)/sections/knowledge-base-graphic.tsx delete mode 100644 docs/src/app/(home)/sections/made-for-agents-preview.tsx delete mode 100644 docs/src/app/(home)/sections/made-for-agents.tsx delete mode 100644 docs/src/app/(home)/sections/own-your-knowledge.tsx delete mode 100644 docs/src/app/(home)/sections/put-it-to-work.tsx delete mode 100644 docs/src/app/(home)/sections/rich-editing.tsx delete mode 100644 docs/src/app/(home)/site-nav.tsx rename docs/src/{app/(home) => components}/dot-texture.tsx (100%) rename docs/src/{app/(home) => components}/footer.tsx (100%) delete mode 100644 docs/src/components/logo-context-menu.tsx rename docs/src/{app/(home) => components}/marketing-button.tsx (100%) delete mode 100644 docs/src/components/ok-editor/block-type-selector.tsx delete mode 100644 docs/src/components/ok-editor/bubble-menu.tsx delete mode 100644 docs/src/components/ok-editor/drag-handle.tsx delete mode 100644 docs/src/components/ok-editor/mode-toggle.tsx delete mode 100644 docs/src/components/ok-editor/ok-editor.css delete mode 100644 docs/src/components/ok-editor/ok-editor.tsx delete mode 100644 docs/src/components/ok-editor/preview-code-block.tsx delete mode 100644 docs/src/components/ok-editor/seed.ts delete mode 100644 docs/src/components/ok-editor/slash-command.tsx delete mode 100644 docs/src/components/ok-editor/slash-items.tsx delete mode 100644 docs/src/components/ok-editor/slash-menu.tsx delete mode 100644 docs/src/components/ok-editor/source-editor.tsx delete mode 100644 docs/src/components/ok-icon.tsx rename docs/src/{app/(home) => components}/section-heading.tsx (100%) delete mode 100644 docs/src/components/ui/context-menu.tsx delete mode 100644 docs/src/components/ui/sheet.tsx delete mode 100644 docs/src/components/ui/tooltip.tsx delete mode 100644 docs/src/lib/copy-svg.ts delete mode 100644 docs/src/lib/use-is-in-view.ts delete mode 100644 docs/src/lib/use-prefers-reduced-motion.ts rename docs/src/{middleware.test.ts => proxy.test.ts} (94%) rename docs/src/{middleware.ts => proxy.ts} (90%) diff --git a/bun.lock b/bun.lock index d7b4bfc89..b899f4e4f 100644 --- a/bun.lock +++ b/bun.lock @@ -21,23 +21,12 @@ "name": "@inkeep/open-knowledge-docs", "version": "0.0.8", "dependencies": { - "@codemirror/commands": "^6.10.3", - "@codemirror/lang-markdown": "^6.5.0", - "@codemirror/language": "^6.12.3", - "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.41.0", - "@floating-ui/dom": "^1.7.6", "@hookform/resolvers": "^5.4.0", "@inkeep/cxkit-react": "^0.5.117", "@inkeep/open-knowledge-core": "workspace:*", "@radix-ui/react-popover": "^1.1.17", - "@tiptap/core": "^3.22.3", - "@tiptap/extension-drag-handle": "3.22.3", - "@tiptap/extensions": "^3.22.3", - "@tiptap/pm": "^3.22.3", - "@tiptap/react": "^3.22.3", - "@tiptap/suggestion": "^3.22.3", "@types/mdx": "^2.0.13", + "@vercel/microfrontends": "^2.3.6", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "fumadocs-core": "~16.1.0", @@ -1138,7 +1127,7 @@ "@napi-rs/wasm-tools-win32-x64-msvc": ["@napi-rs/wasm-tools-win32-x64-msvc@1.0.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rEAf05nol3e3eei2sRButmgXP+6ATgm0/38MKhz9Isne82T4rPIMYsCIFj0kOisaGeVwoi2fnm7O9oWp5YVnYQ=="], - "@next/env": ["@next/env@16.2.3", "", {}, "sha512-ZWXyj4uNu4GCWQw9cjRxWlbD+33mcDszIo9iQxFnBX3Wmgq9ulaSJcl6VhuWx5pCWqqD+9W6Wfz7N0lM5lYPMA=="], + "@next/env": ["@next/env@16.0.10", "", {}, "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang=="], "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-u37KDKTKQ+OQLvY+z7SNXixwo4Q2/IAJFDzU1fYe66IbCE51aDSAzkNDkWmLN0yjTUh4BKBd+hb69jYn6qqqSg=="], @@ -1902,6 +1891,8 @@ "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + "@types/md5": ["@types/md5@2.3.6", "", {}, "sha512-WD69gNXtRBnpknfZcb4TRQ0XJQbUPZcai/Qdhmka3sxUR3Et8NrXoeAoknG/LghYHTf4ve795rInVYHBTQdNVA=="], + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], @@ -1968,6 +1959,8 @@ "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="], + "@vercel/microfrontends": ["@vercel/microfrontends@2.3.6", "", { "dependencies": { "@next/env": "16.0.10", "@types/md5": "^2.3.5", "ajv": "^8.17.1", "commander": "^12.1.0", "cookie": "1.0.2", "fast-glob": "^3.3.2", "http-proxy": "^1.18.1", "jsonc-parser": "^3.3.1", "md5": "^2.3.0", "nanoid": "^3.3.9", "path-to-regexp": "6.3.0", "semver": "^7.7.2" }, "peerDependencies": { "@sveltejs/kit": ">=1", "@vercel/analytics": ">=1.5.0", "@vercel/speed-insights": ">=1.2.0", "next": ">=13", "react": ">=17.0.0", "react-dom": ">=17.0.0", "vite": ">=5" }, "optionalPeers": ["@sveltejs/kit", "@vercel/analytics", "@vercel/speed-insights", "next", "react", "react-dom", "vite"], "bin": { "microfrontends": "cli/index.cjs" } }, "sha512-iMgZp5wmNWMeFO8Sg4BlzshjsjbiXfnIOOGwcFWWb+90nrySy6YV0fgXxj2ZubDGFa6BwWD/Mh/fKKXr4I+iuQ=="], + "@vimeo/player": ["@vimeo/player@2.30.4", "", { "dependencies": { "native-promise-only": "0.8.1", "weakmap-polyfill": "2.0.4" } }, "sha512-M8m1UAhJSb+KCWuXDLWHViwj+3YY/0ogwFquRfMHs9e9LYjXT9iB7n+sOCKwUusbiXuU2HKmXx+FEGHtYZfUSg=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.1", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.7" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ=="], @@ -2212,6 +2205,8 @@ "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], + "charenc": ["charenc@0.0.2", "", {}, "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="], + "chevrotain": ["chevrotain@12.0.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "12.0.0", "@chevrotain/gast": "12.0.0", "@chevrotain/regexp-to-ast": "12.0.0", "@chevrotain/types": "12.0.0", "@chevrotain/utils": "12.0.0" } }, "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ=="], "chevrotain-allstar": ["chevrotain-allstar@0.4.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^12.0.0" } }, "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA=="], @@ -2298,7 +2293,7 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], @@ -2322,6 +2317,8 @@ "crossws": ["crossws@0.4.4", "", { "peerDependencies": { "srvx": ">=0.7.1" }, "optionalPeers": ["srvx"] }, "sha512-w6c4OdpRNnudVmcgr7brb/+/HmYjMQvYToO/oTrprTwxRUiom3LYWU1PMWuD006okbUWpII1Ea9/+kwpUfmyRg=="], + "crypt": ["crypt@0.0.2", "", {}, "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="], + "css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], @@ -2704,6 +2701,8 @@ "float-tooltip": ["float-tooltip@1.7.5", "", { "dependencies": { "d3-selection": "2 - 3", "kapsule": "^1.16", "preact": "10" } }, "sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg=="], + "follow-redirects": ["follow-redirects@1.16.0", "", { "peerDependencies": { "debug": "*" }, "optionalPeers": ["debug"] }, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], + "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], "force-graph": ["force-graph@1.51.2", "", { "dependencies": { "@tweenjs/tween.js": "18 - 25", "accessor-fn": "1", "bezier-js": "3 - 6", "canvas-color-tracker": "^1.3", "d3-array": "1 - 3", "d3-drag": "2 - 3", "d3-force-3d": "2 - 3", "d3-scale": "1 - 4", "d3-scale-chromatic": "1 - 3", "d3-selection": "2 - 3", "d3-zoom": "2 - 3", "float-tooltip": "^1.7", "index-array-by": "1", "kapsule": "^1.16", "lodash-es": "4" } }, "sha512-zZNdMqx8qIQGurgnbgYIUsdXxSfvhfRSIdncsKGv/twUOZpwCsk9hPHmdjdcme1+epATgb41G0rkIGHJ0Wydng=="], @@ -2880,6 +2879,8 @@ "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + "http-proxy": ["http-proxy@1.18.1", "", { "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } }, "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ=="], + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], @@ -2948,6 +2949,8 @@ "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="], + "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], + "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="], "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], @@ -3190,6 +3193,8 @@ "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + "md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="], + "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], @@ -3532,7 +3537,7 @@ "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], @@ -3812,6 +3817,8 @@ "require-in-the-middle": ["require-in-the-middle@7.5.2", "", { "dependencies": { "debug": "^4.3.5", "module-details-from-path": "^1.0.3", "resolve": "^1.22.8" } }, "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ=="], + "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="], + "resedit": ["resedit@1.7.2", "", { "dependencies": { "pe-library": "^0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], "resend": ["resend@6.16.0", "", { "dependencies": { "postal-mime": "2.7.4", "standardwebhooks": "1.0.0" }, "peerDependencies": { "@react-email/render": "*" }, "optionalPeers": ["@react-email/render"] }, "sha512-SaKISwHtxvAxneF84Njgnzg+zdngUu1vOT/paRU1De9QF+zXQR3GnwJHSh+mpJPjUhsGD4WxYi5CfKkXMkDqwg=="], @@ -4598,6 +4605,8 @@ "@types/yauzl/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], + "@vercel/microfrontends/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + "ajv-keywords/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], "app-builder-lib/@electron/fuses": ["@electron/fuses@1.8.0", "", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], @@ -4678,6 +4687,8 @@ "estimo/nanoid": ["nanoid@5.1.5", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw=="], + "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], "filelist/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], @@ -4690,6 +4701,8 @@ "formdata-node/web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], + "fumadocs-core/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + "fumadocs-mdx/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], "fumadocs-mdx/lru-cache": ["lru-cache@11.3.3", "", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="], @@ -4716,6 +4729,8 @@ "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + "http-proxy/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], + "iconv-corefoundation/cli-truncate": ["cli-truncate@2.1.0", "", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="], "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], @@ -4752,7 +4767,7 @@ "msw/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - "msw/path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], + "next/@next/env": ["@next/env@16.2.3", "", {}, "sha512-ZWXyj4uNu4GCWQw9cjRxWlbD+33mcDszIo9iQxFnBX3Wmgq9ulaSJcl6VhuWx5pCWqqD+9W6Wfz7N0lM5lYPMA=="], "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], @@ -4846,6 +4861,8 @@ "rolldown-plugin-dts/get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + "seek-bzip/commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="], "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], diff --git a/docs/next.config.ts b/docs/next.config.ts index 6ba8a0ac5..195cc665e 100644 --- a/docs/next.config.ts +++ b/docs/next.config.ts @@ -1,6 +1,13 @@ +import { existsSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { withMicrofrontends } from '@vercel/microfrontends/next/config'; import { createMDX } from 'fumadocs-mdx/next'; import type { NextConfig } from 'next'; +// Routing home is `/docs` — this app serves no landing page at `/`. In the +// production deployment the apex `/` is served by a separate app, so `/` never +// reaches this project there; a standalone deployment should set its default +// route to `/docs`. const nextConfig: NextConfig = { reactStrictMode: true, reactCompiler: { @@ -125,5 +132,13 @@ const nextConfig: NextConfig = { }; const withMDX = createMDX(); +const baseConfig = withMDX(nextConfig); -export default withMDX(nextConfig); +// `withMicrofrontends` requires a microfrontends.json that declares this app. That +// file names the private marketing app and is a Microfrontends deploy concern of +// agents-private only, so it is excluded from the public mirror — the standalone +// OSS docs build has none. Apply the wrapper only when the config is present, +// leaving the mirror (and any standalone clone) a plain Next.js app. +const microfrontendsConfig = fileURLToPath(new URL('./microfrontends.json', import.meta.url)); + +export default existsSync(microfrontendsConfig) ? withMicrofrontends(baseConfig) : baseConfig; diff --git a/docs/package.json b/docs/package.json index 05a2f992e..94518aa0d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,23 +17,12 @@ "postinstall": "fumadocs-mdx" }, "dependencies": { - "@codemirror/commands": "^6.10.3", - "@codemirror/lang-markdown": "^6.5.0", - "@codemirror/language": "^6.12.3", - "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.41.0", - "@floating-ui/dom": "^1.7.6", "@hookform/resolvers": "^5.4.0", "@inkeep/cxkit-react": "^0.5.117", "@inkeep/open-knowledge-core": "workspace:*", "@radix-ui/react-popover": "^1.1.17", - "@tiptap/core": "^3.22.3", - "@tiptap/extension-drag-handle": "3.22.3", - "@tiptap/extensions": "^3.22.3", - "@tiptap/pm": "^3.22.3", - "@tiptap/react": "^3.22.3", - "@tiptap/suggestion": "^3.22.3", "@types/mdx": "^2.0.13", + "@vercel/microfrontends": "^2.3.6", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "fumadocs-core": "~16.1.0", diff --git a/docs/src/app/(home)/brand/page.tsx b/docs/src/app/(home)/brand/page.tsx index 7bbd0e50f..13b70e914 100644 --- a/docs/src/app/(home)/brand/page.tsx +++ b/docs/src/app/(home)/brand/page.tsx @@ -1,9 +1,9 @@ import type { Metadata } from 'next'; +import { SiteFooter } from '@/components/footer'; +import { MarketingButton } from '@/components/marketing-button'; +import SectionHeading from '@/components/section-heading'; import { BRAND_ASSETS, BRAND_ROUTE, BRAND_ZIP } from '@/lib/brand-assets'; import { cn } from '@/lib/utils'; -import { SiteFooter } from '../footer'; -import { MarketingButton } from '../marketing-button'; -import SectionHeading from '../section-heading'; export const metadata: Metadata = { title: 'Brand assets', diff --git a/docs/src/app/(home)/feature-item.tsx b/docs/src/app/(home)/feature-item.tsx deleted file mode 100644 index 738492bb7..000000000 --- a/docs/src/app/(home)/feature-item.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { LucideIcon } from 'lucide-react'; -import { cn } from '@/lib/utils'; - -interface FeatureItemProps { - icon: LucideIcon; - title: string; - description: string; - className?: string; -} - -const FeatureItem = ({ icon: Icon, title, description, className }: FeatureItemProps) => { - return ( -
-
- -
-
-

{title}

-

{description}

-
-
- ); -}; - -export default FeatureItem; diff --git a/docs/src/app/(home)/layout.tsx b/docs/src/app/(home)/layout.tsx deleted file mode 100644 index d252fb144..000000000 --- a/docs/src/app/(home)/layout.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { getGitHubStars } from '@inkeep/open-knowledge-core'; -import { SiteNav } from './site-nav'; - -export default async function Layout({ children }: LayoutProps<'/'>) { - const stars = await getGitHubStars({ next: { revalidate: 3600 } }); - return ( - <> - -
{children}
- - ); -} diff --git a/docs/src/app/(home)/page.tsx b/docs/src/app/(home)/page.tsx deleted file mode 100644 index a75eac588..000000000 --- a/docs/src/app/(home)/page.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import type { SoftwareApplication, WithContext } from 'schema-dts'; -import { JsonLd } from '@/components/seo/json-ld'; -import { DOWNLOAD_URL, GITHUB_URL, SITE_DESCRIPTION, SITE_NAME, SITE_URL } from '@/lib/site'; -import { SiteFooter } from './footer'; -import { CallToAction } from './sections/call-to-action'; -import { Collaboration } from './sections/collaboration'; -import { Hero } from './sections/hero'; -import { MadeForAgents } from './sections/made-for-agents'; -import { OwnYourKnowledge } from './sections/own-your-knowledge'; -import { PutItToWork } from './sections/put-it-to-work'; -import { RichEditing } from './sections/rich-editing'; - -const softwareAppLd = { - '@context': 'https://schema.org', - '@type': 'SoftwareApplication', - name: SITE_NAME, - applicationCategory: 'DeveloperApplication', - operatingSystem: 'macOS', - url: SITE_URL, - downloadUrl: DOWNLOAD_URL, - description: SITE_DESCRIPTION, - isAccessibleForFree: true, - offers: { - '@type': 'Offer', - price: '0', - priceCurrency: 'USD', - }, - author: { - '@type': 'Organization', - name: 'Inkeep', - url: 'https://inkeep.com', - }, - sameAs: GITHUB_URL, -} satisfies WithContext; - -export default function HomePage() { - return ( -
- - - - - - - - - -
- ); -} diff --git a/docs/src/app/(home)/section.tsx b/docs/src/app/(home)/section.tsx deleted file mode 100644 index 208a20ba2..000000000 --- a/docs/src/app/(home)/section.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { cn } from '@/lib/utils'; - -export function Section({ - children, - className, -}: { - children: React.ReactNode; - className?: string; -}) { - return ( -
{children}
- ); -} diff --git a/docs/src/app/(home)/sections/agent-brain-graphic.tsx b/docs/src/app/(home)/sections/agent-brain-graphic.tsx deleted file mode 100644 index bce9d3d3e..000000000 --- a/docs/src/app/(home)/sections/agent-brain-graphic.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import { - Box, - Code, - FileText, - Globe, - type LucideIcon, - MessageCircleMore, - Sparkles, - User, -} from 'lucide-react'; - -const RINGS = [20, 44, 68, 94] as const; - -type Bubble = { icon: LucideIcon; angle: number; radius: number }; - -const BUBBLES: Bubble[] = [ - { icon: Globe, angle: 8, radius: 68 }, // right, outer ring - { icon: User, angle: 65, radius: 44 }, // upper-right, inner ring - { icon: FileText, angle: 128, radius: 68 }, // upper-left, outer ring - { icon: MessageCircleMore, angle: 185, radius: 44 }, // left, inner ring - { icon: Code, angle: 248, radius: 68 }, // lower-left, outer ring - { icon: Box, angle: 305, radius: 44 }, // lower-right, inner ring -]; - -const CENTER = { x: 80, y: 45 }; - -function orbitMotion(radius: number) { - return radius > 50 - ? { duration: 130, direction: 'reverse' as const } - : { duration: 90, direction: 'normal' as const }; -} - -function AgentMark() { - return ( -
-
- ); -} - -export function AgentBrainGraphic() { - return ( - - ); -} diff --git a/docs/src/app/(home)/sections/call-to-action.tsx b/docs/src/app/(home)/sections/call-to-action.tsx deleted file mode 100644 index 56a437073..000000000 --- a/docs/src/app/(home)/sections/call-to-action.tsx +++ /dev/null @@ -1,126 +0,0 @@ -'use client'; - -import Image from 'next/image'; -import Link from 'next/link'; -import { useEffect, useState } from 'react'; -import { DOWNLOAD_ROUTE } from '@/lib/site'; -import { useIsInView } from '@/lib/use-is-in-view'; -import { cn } from '@/lib/utils'; -import { DotTexture } from '../dot-texture'; -import { MarketingButton } from '../marketing-button'; -import { Section } from '../section'; -import SectionHeading from '../section-heading'; - -/* Two soft organic shapes drift toward center while blurring when the section - scrolls into view, overlapping behind the headline. multiply darkens the - overlap into a richer blue on the light background; screen is the dark-mode - equivalent (multiply over near-black renders the shapes invisible). */ -function CtaShape({ - src, - width, - height, - settled, - wrapperClassName, - imageClassName, - fromX, - toX, -}: { - src: string; - width: number; - height: number; - settled: boolean; - wrapperClassName?: string; - imageClassName?: string; - fromX: string; - toX: string; -}) { - return ( -
- -
- ); -} - -export function CallToAction() { - const [stageRef, inView] = useIsInView('-15%'); - const [settled, setSettled] = useState(false); - useEffect(() => { - if (inView) setSettled(true); - }, [inView]); - - return ( -
- - - -
- - - -
- - Start building knowledge. - - -
- - DOWNLOAD FOR MAC - - - More platforms - -
-
-
-
- ); -} diff --git a/docs/src/app/(home)/sections/collaboration.tsx b/docs/src/app/(home)/sections/collaboration.tsx deleted file mode 100644 index d52fcb3e7..000000000 --- a/docs/src/app/(home)/sections/collaboration.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import { GitBranch, type LucideIcon, MousePointerClick, Share2, Sparkle } from 'lucide-react'; -import type { ReactNode, SVGProps } from 'react'; -import { ClaudeIcon } from '@/components/icons/claude'; -import { CodexBrandMonoIcon } from '@/components/icons/codex'; -import { Section } from '../section'; -import SectionHeading from '../section-heading'; - -const CLAUDE_BRAND = '#D97757'; - -type EditorTint = { - highlightBg: string; - badgeBg: string; - badgeText: string; -}; - -const CLAUDE_TINT: EditorTint = { - highlightBg: 'color-mix(in srgb, var(--color-orange-light) 80%, transparent)', - badgeBg: CLAUDE_BRAND, - badgeText: '#ffffff', -}; - -const ALAN_TINT: EditorTint = { - highlightBg: 'color-mix(in srgb, var(--color-crystal-blue) 70%, transparent)', - badgeBg: 'var(--color-azure-blue)', - badgeText: '#ffffff', -}; - -const CODEX_TINT: EditorTint = { - highlightBg: 'color-mix(in srgb, var(--color-purple-light) 70%, transparent)', - badgeBg: '#7c6df0', - badgeText: '#ffffff', -}; - -function ShareButton() { - return ( - - ); -} - -function PresenceAvatars() { - return ( -
- {/* Icon-based "agent" avatars use a white plate + thin colored ring so the - brand mark stays legible. Text-initial "human" avatars (Alan) keep the - solid-color treatment so the initial reads at high contrast. */} - - - A - - - - - - -
- ); -} - -function PresenceAvatar({ - tint, - ringClass, - children, -}: { - tint: EditorTint; - ringClass: string; - children: ReactNode; -}) { - return ( - - ); -} - -function Highlight({ - tint, - name, - icon: Icon, - children, -}: { - tint: EditorTint; - name: string; - icon?: (props: SVGProps) => ReactNode; - children: ReactNode; -}) { - return ( - - {children} - {/* Inline-block anchor at the trailing edge of the last line. Holds both - the caret and the floating name badge so they stay glued together when - the highlight wraps across lines (absolute positioning on the outer - span otherwise stretches the caret across both line boxes and floats - the badge over the first line). */} - - - - ); -} - -function CollaborationPreview() { - return ( -
- {/* Document chrome — filename + presence */} -
- roadmap.md -
- - -
-
- - {/* Document body */} -
-

- Q3 Roadmap -

- -

- We’re bringing the whole team into{' '} - - one shared workspace - - , where people and agents edit the same files instead of losing context in a thread. -

- -
- This quarter -
    -
  • - - - Ship the{' '} - - collaborative editor - {' '} - for docs and spaces - -
  • -
  • - - One click to share a doc, or a whole workspace -
  • -
  • - - - - - Git-backed sync so history and ownership stay yours - - - -
  • -
-
-
-
- ); -} - -function Bullet() { - return ( -