Skip to content

Latest commit

 

History

40 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Branchmark

Multi-app MDX public hub with a Git-backed static CMS admin and an MCP docs endpoint.

Own your multi-product What’s New / features hub in Git — with MR editorial and agent MCP — not another hosted changelog widget.

Live demo: https://branchmark-demo.vercel.app · Repo: https://github.com/0xTHAC0/branchmark (public MIT template)

Who it’s for

  • Documentation / product teams that want blog, timeline, and pages from MDX in Git
  • Orgs on GitLab that want PKCE editors → staging MRs without a hosted CMS database
  • Multi-product teams registering several hubs in one repo (content/public/_apps.yml)
  • AI agents reading hub content via POST /mcp

Who it’s not for

  • Teams that need email digests, unread segmentation, or feedback voting (Beamer / Canny territory)
  • Teams that need a shipped GitHub OAuth CMS API today (typed / reserved; not implemented)

The sample apps are demo (default) and northstar (second product for AppSwitcher). Add more via _apps.yml.

Features

Capability Status
Marketing landing (/) Own
Public hub (blog / timeline / markdown pages) Own
Multi-app registry Own
Static admin — GitLab PKCE (/admin) Own
What’s New JSON feed Own
What’s New embed (inline script) Own
AI draft What’s New from MRs Own (needs AI_GATEWAY_API_KEY)
Hub analytics (view / Cmd+K) Own (needs HUB_ANALYTICS_WEBHOOK_URL)
Admin Insights dashboard Own (needs BLOB_READ_WRITE_TOKEN or HUB_ANALYTICS_JSONL_PATH)
sitemap.xml / robots.txt Own
MCP read tools (search_docs, get_page, …) Own
llms.txt / llms-full.txt / /md/* agent mirrors Own
GitHub OAuth CMS route handlers Not shipped
Hub Cmd+K search Own
Admin history + releases Own
Draft MR preview links (Admin discovery) Own
Review App hosting / live preview deploy Operator (Docker CI + preview host — docs/review-apps.md)
Shared published docs-kit MCP package Own (@cmsmark/docs-kit-mcp)
Email digests / unread targeting Not shipped
  • Marketing landing — / brand-first page with CTAs to the demo hub and admin
  • Public hub — per-app routes for blog, timeline (features / release notes / changelog), and markdown pages
  • Multi-app registry — register apps in content/public/_apps.yml
  • Static admin — /admin GitLab PKCE editor for content, workflow, media, history, and releases (draft → review → ready via MR labels; Preview when Review App env URL exists; live GFM body preview beside Source; Publish squash + delete cms/* when configured)
  • MCP — POST /mcp tools for listing and fetching hub pages (@cmsmark/docs-kit-mcp)
  • Write MCP (stdio) — privileged npm run mcp:write tools that open/update draft MRs (no merge); token never on public /mcp
  • Agent index — GET /llms.txt, /llms-full.txt, /md/..., /agent-readability.json
  • What’s New — GET /[app]/whats-new.json built from Release Notes timeline entries (CORS enabled for embeds)
  • What’s New RSS — GET /[app]/whats-new.xml (RSS 2.0; classic readers, no CORS required)
  • What’s New embed — /embed/branchmark-whats-new.js + demo at /embed
  • AI draft from MRs — Workflow “Draft What’s New” (optional; requires AI_GATEWAY_API_KEY; uses title, description, labels, commits, and a size-capped MR file diff)
  • Hub analytics — opt-in webhook for section views and Cmd+K open/select (HUB_ANALYTICS_WEBHOOK_URL); no cookies, no product-analytics SaaS
  • Admin Insights — read-only /admin/.../insights dashboard when BLOB_READ_WRITE_TOKEN (Vercel Blob) or HUB_ANALYTICS_JSONL_PATH is set; beacons persist alongside optional webhook forward
  • SEO — GET /sitemap.xml (landing + public hubs/sections/posts) and GET /robots.txt (allows public; disallows /admin and /api); Open Graph / Twitter cards use /og.png with absolute URLs via BRANCHMARK_PUBLIC_URL
  • Review Apps — .gitlab-ci.yml builds/pushes a Docker image and registers environment:url for Admin Preview; optional SSH deploy (docs/review-apps.md)

Quick start (proof path)

npm install
cp .env.example .env.local
# For /admin: set GITLAB_CLIENT_ID (GitLab OAuth Application ID, PKCE)
npm run dev

Open http://localhost:3007 — Branchmark marketing landing (not an instant redirect).

  1. Landing: brand + Open demo hub → http://localhost:3007/demo
  2. Hub changelog: http://localhost:3007/demo/change-log
  3. What’s New feed: http://localhost:3007/demo/whats-new.json · RSS: http://localhost:3007/demo/whats-new.xml
  4. Second app (multi-app): http://localhost:3007/northstar — use the hub AppSwitcher between Demo and Northstar
  5. MCP: POST http://localhost:3007/mcp with tools such as search_docs / list_pages
  6. Agent index: http://localhost:3007/llms.txt and raw markdown http://localhost:3007/md/demo/pages/overview (also /md/northstar/pages/overview)
  7. What’s New embed demo: http://localhost:3007/embed

Consume What’s New from your product

JSON feed

const res = await fetch("https://your-host/demo/whats-new.json");
const feed = await res.json();
// feed.items: { title, description, date, category, tags, imageUrl, ... }

Inline embed

<div
  data-branchmark-whats-new
  data-hub="https://your-host"
  data-app="demo"
  data-limit="5"
  data-theme="auto"
></div>
<script src="https://your-host/embed/branchmark-whats-new.js" defer></script>

Content layout

content/public/_apps.yml          # app registry
content/public/<app>/sections/    # nav + layouts
content/public/<app>/posts/       # blog posts
content/public/<app>/timeline/    # features / release notes / changelog
content/public/<app>/pages/       # long-form pages
content/docs/                     # CMS docs tree

Changelog = finer activity stream. Release Notes = curated highlights that feed What’s New. Tag timeline MDX with sections: [change-log] and/or sections: [release-notes].

Section gotchas:

  • hide: true removes the section from nav (route may still exist)
  • Section body matching Coming Soon (case-insensitive) forces the Coming Soon UI for non-timeline layouts. For timeline layouts, tagged entries still render even if the body is Coming Soon; empty timelines with that body show Coming Soon, otherwise an empty state.

Regenerate derived data after content changes:

npm run generate:agent
npm run generate:whats-new

Write MCP (stdio)

Privileged local MCP for agents that performs the same branch → draft MR loop as /admin: create_page, save_draft, set_status, get_draft, list_drafts. No merge. Public POST /mcp stays read-only — never wire GITLAB_TOKEN into the HTTP MCP route.

# Set GITLAB_TOKEN and a real repo in public/admin/config.yml (or BRANCHMARK_REPO)
npm run mcp:write

Copy .cursor/mcp.json.example into your MCP config. Paths are under content/public/ (relative demo/pages/foo.mdx or full). Helpers live in scripts/lib/gitlab-writes.mjs.

Scripts

Script Purpose
npm run dev Next.js on port 3007
npm run build / npm start Production build and server
npm test Vitest unit/component tests
npm run test:e2e Playwright smoke tests
npm run generate:mcp-data Build generated/mcp-data.json
npm run generate:llms-txt Build generated/llms.txt + llms-full.txt
npm run generate:agent MCP data + llms artifacts
npm run generate:whats-new Build What's New feeds (static/Pages exports)
npm run mcp:write Privileged stdio Write MCP (draft MRs; requires GITLAB_TOKEN)

See PACKAGING.md for Docker, env truth table, and release checklist.

Docker

docker build -t branchmark .
docker run -p 3007:3007 branchmark

License

MIT — see LICENSE. Template, not a hosted SaaS. See CONTRIBUTING.md.

About

Own your multi-product What’s New / features hub in Git — multi-app MDX, GitLab PKCE admin, MCP.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages