docs: add cloudflare documentation deployment website#1285
Conversation
Add a self-contained marketing + documentation site under website/, built with Fumadocs (Next.js) and configured as a static export so it deploys directly to Cloudflare Pages with no server runtime. What's included: - A marketing landing page (hero, the two-folder model, the four core ideas, the explore→propose→apply→archive loop, and the "why"). - 13 documentation pages rewritten for clarity and delight: introduction, installation, getting started, how commands work, core concepts, the workflow, explore first, existing projects, editing a change, customization, FAQ, and a reference section (slash commands, CLI, supported tools). - Static client-side search (Orama), per-page Open Graph images, and llms.txt / llms-full.txt routes — fitting for an AI-native tool. - website/README.md with one-table Cloudflare Pages deploy settings (root: website, build: npm run build, output: out). Content is faithful to the docs/ overhaul from Fission-AI#1237, restated in a simpler, friendlier voice. Verified with a clean `next build` (48 static pages, no warnings). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughA static ChangesOpenSpec Documentation Website
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Completes the documentation work begun in Fission-AI#1237 by tightening the Fumadocs site toward the quality bar of the stores user-guide: - Intro now opens problem-first ("the requirements lived only in chat"), adds an honest "How it compares" table (Spec Kit / Kiro / nothing), and frames the tradeoff in a "When the ceremony isn't worth it" callout. - New Stores guide (beta) distilled from docs/stores-beta/user-guide.md: the problem, the annotated shape, a five-minute walkthrough with real command output, a role-based story, the root-resolution order, and an honest-limitations section. Linked from Existing Projects. Verified with a clean `next build` (51 static pages, no warnings). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
website/content/docs/installation.mdx (1)
26-30: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winYarn Berry users may be confused by
yarn global add.Modern Yarn (2+/Berry) no longer supports
yarn global addby default. Consider adding a note for Yarn Berry users or usingyarn dlx@fission-ai/openspec`` for one-off execution.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@website/content/docs/installation.mdx` around lines 26 - 30, The installation example in the yarn tab uses a command that no longer works for Yarn Berry users. Update the docs around the installation snippet in the installation.mdx content to either add a clear note that `yarn global add` is only for classic Yarn, or replace/augment it with the Yarn Berry-friendly `yarn dlx `@fission-ai/openspec`` option. Keep the guidance near the existing yarn example so users can choose the right command based on their Yarn version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@website/app/docs/`[[...slug]]/page.tsx:
- Around line 30-33: The GitHub link built in the docs page view uses the wrong
blob path and points to content/docs/... instead of the actual
website/content/docs/... location. Update the githubUrl construction in the page
component that renders ViewOptionsPopover so the generated link is prefixed with
website/ and matches the repo path for these docs pages.
---
Nitpick comments:
In `@website/content/docs/installation.mdx`:
- Around line 26-30: The installation example in the yarn tab uses a command
that no longer works for Yarn Berry users. Update the docs around the
installation snippet in the installation.mdx content to either add a clear note
that `yarn global add` is only for classic Yarn, or replace/augment it with the
Yarn Berry-friendly `yarn dlx `@fission-ai/openspec`` option. Keep the guidance
near the existing yarn example so users can choose the right command based on
their Yarn version.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0c48f2d6-06fa-4bce-bb61-5d96ddd872f6
⛔ Files ignored due to path filters (1)
website/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (41)
website/.gitignorewebsite/README.mdwebsite/app/(home)/layout.tsxwebsite/app/(home)/page.tsxwebsite/app/api/search/route.tswebsite/app/docs/[[...slug]]/page.tsxwebsite/app/docs/layout.tsxwebsite/app/global.csswebsite/app/layout.tsxwebsite/app/llms-full.txt/route.tswebsite/app/llms.mdx/docs/[[...slug]]/route.tswebsite/app/llms.txt/route.tswebsite/app/og/docs/[...slug]/route.tsxwebsite/components/mdx.tsxwebsite/components/provider.tsxwebsite/components/search.tsxwebsite/content/docs/core-concepts.mdxwebsite/content/docs/customization.mdxwebsite/content/docs/editing-changes.mdxwebsite/content/docs/existing-projects.mdxwebsite/content/docs/explore.mdxwebsite/content/docs/faq.mdxwebsite/content/docs/getting-started.mdxwebsite/content/docs/how-commands-work.mdxwebsite/content/docs/index.mdxwebsite/content/docs/installation.mdxwebsite/content/docs/meta.jsonwebsite/content/docs/reference/cli.mdxwebsite/content/docs/reference/meta.jsonwebsite/content/docs/reference/slash-commands.mdxwebsite/content/docs/reference/supported-tools.mdxwebsite/content/docs/the-workflow.mdxwebsite/lib/cn.tswebsite/lib/layout.shared.tsxwebsite/lib/shared.tswebsite/lib/source.tswebsite/next.config.mjswebsite/package.jsonwebsite/postcss.config.mjswebsite/source.config.tswebsite/tsconfig.json
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@website/content/docs/index.mdx`:
- Around line 76-81: The comparison table in the docs has an unlabeled first
column, so update the markdown table in the index content to give that header an
explicit name such as Tool or Option. Keep the existing table structure and
ensure the first column header in the OpenSpec/Spec Kit/Kiro comparison is
clearly labeled so the table is easier to scan and more accessible.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a83a1878-aa75-4c4c-9098-f70581fd9c43
📒 Files selected for processing (4)
website/content/docs/existing-projects.mdxwebsite/content/docs/index.mdxwebsite/content/docs/meta.jsonwebsite/content/docs/stores.mdx
✅ Files skipped from review due to trivial changes (2)
- website/content/docs/meta.json
- website/content/docs/existing-projects.mdx
…page Continue the Fission-AI#1237 docs completion with a stronger product story: - Landing page now reads like a real product site: - "Works with the tools you already use" strip (15 named assistants + more) - "What a change actually looks like" — three real artifacts (proposal.md, a spec delta, tasks.md) so the workflow is concrete - "The honest middle" comparison block (Spec Kit / Kiro / no specs) - Robust hero gradient via color-mix instead of v3 theme() syntax - New Examples & Recipes page: seven copy-pasteable, narrated walkthroughs (small feature, bug fix, explore-first, parallel changes, no-behavior refactor with --skip-specs, step-by-step, onboard). Linked from the intro and getting-started. Verified: clean `next build` (54 static pages, no warnings); Tailwind opacity/color-mix utilities confirmed in the generated CSS; all internal links resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… site - Branded SVG favicon (app/icon.svg) in the OpenSpec indigo. - Static sitemap.xml covering the home page and every doc, built from the content source and NEXT_PUBLIC_SITE_URL. - robots.txt allowing all and pointing at the sitemap. All three are emitted by the static export. Clean `next build`, 57 pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…overage Final pass completing the Fission-AI#1237 documentation work. Reposition stores (beta) as the team adoption story, consistently: - README.md gains a prominent "Why teams adopt OpenSpec" section right after the demo (cross-repo features, shared requirements, plan before code), leading with stores. - Landing page gains a matching "Why teams adopt OpenSpec" section. - Docs intro gains a teams card + callout pointing at stores. - Stores page expanded with full References and Worksets technical examples (the cross-team requirements story, workset create/open). Incorporate the remaining source-doc knowledge so the site is complete: - New pages: Glossary, Troubleshooting, Multi-Language, and an Agents & Automation reference (the machine-readable --json surfaces and workflow primitives that make OpenSpec AI-native). - The Workflow page now covers ff-vs-continue, a three-dimension verify example, and the update-vs-start-fresh decision guide. - Nav restructured with a Help section; reference section gains Agents. Build hardening: `build` now runs `fumadocs-mdx && next build` so the content source is always regenerated. Clean build: 69 static pages, no warnings; all internal links verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
website/app/(home)/page.tsx (1)
17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse the shared docs route constant.
website/lib/shared.tsalready centralizes the docs base path, so hardcoding/docs/storeshere makes the new section the first place that drifts if that route ever changes.Suggested diff
-import { links } from '`@/lib/shared`'; +import { docsRoute, links } from '`@/lib/shared`'; ... - <Link href="/docs/stores" className="font-medium text-fd-primary underline"> + <Link + href={`${docsRoute}/stores`} + className="font-medium text-fd-primary underline" + > stores </Link> ... - href="/docs/stores" + href={`${docsRoute}/stores`}Also applies to: 379-403
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@website/app/`(home)/page.tsx at line 17, The home page is still hardcoding the docs section path instead of reusing the shared route constant. Update the relevant links in the home page component and any related docs references to use the centralized value from links in website/lib/shared.ts, so the path stays consistent if the docs base route changes. Use the existing imports and identifiers in page.tsx to locate and replace the hardcoded /docs/stores usage with the shared constant.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@website/app/`(home)/page.tsx:
- Line 17: The home page is still hardcoding the docs section path instead of
reusing the shared route constant. Update the relevant links in the home page
component and any related docs references to use the centralized value from
links in website/lib/shared.ts, so the path stays consistent if the docs base
route changes. Use the existing imports and identifiers in page.tsx to locate
and replace the hardcoded /docs/stores usage with the shared constant.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: adc34dd9-9655-4919-91d8-69dd375ac718
📒 Files selected for processing (12)
README.mdwebsite/app/(home)/page.tsxwebsite/content/docs/glossary.mdxwebsite/content/docs/index.mdxwebsite/content/docs/meta.jsonwebsite/content/docs/multi-language.mdxwebsite/content/docs/reference/agents.mdxwebsite/content/docs/reference/meta.jsonwebsite/content/docs/stores.mdxwebsite/content/docs/the-workflow.mdxwebsite/content/docs/troubleshooting.mdxwebsite/package.json
✅ Files skipped from review due to trivial changes (6)
- website/content/docs/reference/meta.json
- README.md
- website/content/docs/reference/agents.mdx
- website/content/docs/the-workflow.mdx
- website/content/docs/stores.mdx
- website/content/docs/index.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
- website/package.json
- website/content/docs/meta.json
alfred-openspec
left a comment
There was a problem hiding this comment.
One blocker before this lands: the docs page GitHub source/edit links point at the wrong path.
website/app/docs/[[...slug]]/page.tsx builds URLs under /content/docs/${page.path}, but these files live under /website/content/docs/${page.path} in this PR. That means the ViewOptionsPopover link will 404 on every deployed docs page.
The rest of the static export shape looks healthy: I ran npm install && npm run build in website/ and it generated 69 static pages successfully.
- page.tsx: prefix ViewOptionsPopover githubUrl with website/ so the
"view/edit source" links resolve to website/content/docs/... instead
of 404-ing on every deployed docs page (Alfred blocker).
- installation.mdx: note that `yarn global add` is Classic Yarn only and
point Yarn Berry users at `yarn dlx` / npm / pnpm.
- index.mdx: label the comparison table's first column ("Option").
- (home)/page.tsx: use the shared docsRoute constant for all /docs links
instead of hardcoded paths.
Verified with `npm run build` in website/ — 69 static pages, and the
built getting-started page links to blob/main/website/content/docs/...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks @alfred-openspec and @coderabbitai — all four points addressed in a726e91:
Re-ran |
|
Tip For best results, initiate chat on the files or code changes.
🐇✨ If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
alfred-openspec
left a comment
There was a problem hiding this comment.
Thanks for addressing this. I rechecked the source links and the built output now points at website/content/docs/...; CI is green, and a fresh npm ci && npm run build in website/ passed locally with 69 static pages. Good to merge.
Make the repository's docs/*.md the single source of truth for the docs
site instead of maintaining a parallel set of hand-written MDX pages that
silently drift.
- scripts/sync-docs.mjs mirrors ../docs into content/docs/ on every build:
derives title/description, injects Fumadocs frontmatter (+ githubSource),
rewrites internal *.md links to /docs routes, and emits meta.json. Pages
are written as .md so <placeholders>/{braces} in the docs stay literal
and never break the MDX build.
- docs.sync.config.mjs is the one manifest deciding which docs publish and
their slug/section/icon. content/docs/ is now generated + git-ignored;
the curated .mdx pages are removed. The marketing landing page stays
hand-authored.
- build/dev/types:check run sync:docs first, so the site is always current.
- .github/workflows/deploy-docs.yml rebuilds and deploys to Cloudflare
Pages via Wrangler on push to docs/**|website/**, daily on a schedule,
on demand, and as a build-only check on PRs. Needs CLOUDFLARE_API_TOKEN
+ CLOUDFLARE_ACCOUNT_ID secrets and the DOCS_SITE_URL variable.
- source.config.ts carries githubSource so "edit this page" opens the real
docs/*.md; website/README.md documents the pipeline.
Verified: clean build, 23 pages generated, 78 static pages, no warnings;
all internal doc links resolve; MDX-hazard docs (cli, customization) build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… is empty
The deploy workflow passes NEXT_PUBLIC_SITE_URL from the DOCS_SITE_URL repo
variable, which resolves to an empty string when unset. `?? fallback` does
not catch '' (only null/undefined), so `metadataBase: new URL('')` crashed
`next build` with ERR_INVALID_URL while collecting page data. Use `||` so an
empty value also falls back. Verified: `NEXT_PUBLIC_SITE_URL='' npm run build`
now generates all 78 static pages.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fill the biggest gaps a new user hits, in the plain-language voice of the stores user guide: - reviewing-changes.md: the two-minute human review of an AI-drafted plan before /opsx:apply — what to open, in what order, and the red flags per artifact — plus the /opsx:verify pass after code. - writing-specs.md: what a strong requirement and scenario are made of, choosing ADDED/MODIFIED/REMOVED, and right-sizing a change. - team-workflow.md: how a change maps onto a branch and a pull request, reviewing spec deltas in a PR, when to archive, and parallel changes — framed as convention, since OpenSpec never touches git. Wire them into the docs map (README), the site nav (docs.sync.config.mjs), and light "next steps" cross-links from getting-started, editing-changes, and workflows. Verified: site builds clean, 26 pages, all internal links resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spell out the three maintainer steps that activate auto-deploy (create the openspec-docs Pages project, add CLOUDFLARE_API_TOKEN/ACCOUNT_ID secrets, merge to main), and note that the pipeline mirrors docs on build regardless. Also flag that openspec.dev is a separate Astro landing page and whether to keep/port this Fumadocs landing page is a maintainer decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alfred-openspec
left a comment
There was a problem hiding this comment.
One deploy-path blocker before merge: the Cloudflare deploy step still runs on push, schedule, and workflow_dispatch whenever the repo is Fission-AI/OpenSpec, even if the one-time Cloudflare setup has not happened yet.
The PR body/README says the pipeline stays dormant until CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID are configured, but missing secrets expand to empty values and this step will try to deploy and fail on main. Please either guard the deploy step on non-empty Cloudflare credentials, or make the setup-before-merge requirement explicit and remove the “dormant” framing.
I rechecked the mirror/build path locally: npm ci, npm run sync:docs, and npm run build all pass, generating 26 mirrored docs and 87 static pages. The docs mirror itself looks healthy.
|
Reviewed the new guide commit too. The three docs additions look strong: reviewing-changes, writing-specs, and team-workflow all fit the product voice, links resolve through the docs mirror, and a fresh website build passes locally with 26 mirrored docs / 87 static pages. The remaining blocker is still the deploy activation path from my review: either guard the Cloudflare deploy step on non-empty secrets, or make setup-before-merge explicit without saying the workflow stays dormant. Right now the README still says dormant, but the workflow would run and fail on main if the secrets/project are missing. |
TabishB
left a comment
There was a problem hiding this comment.
Note
This is an AI-generated review (Claude, running a multi-agent fan-out: 7 domain reviewers — CI/CD, supply chain, sync engine, static-export correctness, docs accuracy, landing page, build verification — with adversarial verification of findings and a full build actually executed). Treat the judgment calls accordingly; every line comment below is anchored to concrete evidence.
Verdict: no blocking issues
Everything found is low-severity or informational. Four items are worth addressing before merge (marked [fix] inline): the production-deploy guard on workflow_dispatch, a phantom zod dependency, the unused cnfast package, and a doubled intro paragraph on every generated docs page. The rest are nits and notes.
What was verified by execution (not just read)
- The PR's claims are true.
npm ci+npm run build+npm run types:checkall pass with zero warnings: exactly 26 docs pages synced, 87/87 static pages — matching the PR description. - All links work. 1,075 internal hrefs across the built
out/resolve to real files; all 43 fragment anchors resolve;git statusstays clean after a full build (generated dirs are properly gitignored). - No hallucinated dependencies. Every version in
website/package.jsonexists on npm and is current; all 443 lockfile entries resolve to registry.npmjs.org with sha512 integrity hashes; no git/tarball deps. - No hallucinated docs. Every CLI command, slash command, flag, and described behavior in the three new guides matches
src/; all internal links resolve both on GitHub and after site rewriting. - No fabricated marketing. The landing page has no invented testimonials/stats; terminal samples trace verbatim to canonical docs; the “15 + 15 more” tools arithmetic is exactly right against the 30 enabled tools in
src/core/config.ts. - Secrets are safe from forks.
pull_requesttrigger (notpull_request_target) withcontents: read, and the only step touching Cloudflare secrets is skipped on PRs. - The docs mirror is lossless and deterministic. Byte-identical output across runs; a masked diff of all 26 generated pages against their sources shows nothing dropped or duplicated; none of the link-rewrite regex edge cases occur in the real corpus.
Nice work overall — this is an unusually clean PR for its size.
|
|
||
| - name: Deploy to Cloudflare Pages | ||
| # Skip on pull requests (build-only check) and on forks without secrets. | ||
| if: ${{ github.event_name != 'pull_request' && github.repository == 'Fission-AI/OpenSpec' }} |
There was a problem hiding this comment.
[fix] A workflow_dispatch from any branch deploys that branch to production.
This condition only excludes pull_request, and the wrangler command below hardcodes --branch=main — which marks the deployment as production regardless of which git ref was actually built. So manually dispatching this workflow on a feature branch (e.g. “just to test the build”) silently overwrites the live docs site.
| if: ${{ github.event_name != 'pull_request' && github.repository == 'Fission-AI/OpenSpec' }} | |
| if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && github.repository == 'Fission-AI/OpenSpec' }} |
Push, schedule, and main-dispatch runs all still satisfy this; non-main dispatches become build-only.
|
|
||
| # Never run two deploys at once; let an in-flight deploy finish. | ||
| concurrency: | ||
| group: deploy-docs |
There was a problem hiding this comment.
[nit] PR checks share this concurrency group with deploys — pending PR runs can get canceled.
GitHub keeps one running + at most one pending run per group, and cancel-in-progress: false only protects the running one. Scenario: a main deploy is running, PR A's build check queues, then PR B (or the cron) triggers → PR A's run is canceled and its check shows as canceled on the PR, which reads like a failure.
Consider scoping PR builds per-ref and only serializing real deploys, e.g.:
concurrency:
group: deploy-docs-${{ github.event_name == 'pull_request' && github.ref || 'deploy' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}| - '.github/workflows/deploy-docs.yml' | ||
| schedule: | ||
| # Daily at 06:00 UTC — picks up any docs changes merged since the last run. | ||
| - cron: '0 6 * * *' |
There was a problem hiding this comment.
[note] The daily cron redeploys byte-identical content.
The build is fully deterministic from repo state (every published page comes from docs/**, and every push to main touching docs/** or website/** already deploys immediately), so the cron only serves as self-healing. Downside: if the Cloudflare token is ever rotated or removed, this produces a failing run every day. Weekly would give the same self-heal with less noise — or drop it entirely. Fine to keep as-is if the liveness signal is wanted.
| }, | ||
| "dependencies": { | ||
| "@orama/orama": "^3.1.18", | ||
| "cnfast": "^0.0.8", |
There was a problem hiding this comment.
[fix] cnfast is dead code — nothing imports it.
The only reference in the whole tree is website/lib/cn.ts (export { cn } from 'cnfast';), and nothing imports lib/cn or calls cn( anywhere. The package itself was inspected and is benign (author Aiden Bai, no install scripts), but it's a 13-day-old pre-1.0 single-maintainer package — pure supply-chain surface for zero benefit.
Suggest removing it from dependencies and deleting website/lib/cn.ts. If a class-merge helper is needed later, clsx is already in the lockfile as a transitive dep.
| "fumadocs-mdx": "^15.0.13", | ||
| "fumadocs-ui": "^16.10.7", | ||
| "lucide-react": "^1.22.0", | ||
| "next": "16.2.9", |
There was a problem hiding this comment.
[note] npm audit shows 5 moderate advisories — all upstream in Next itself, not fixable here.
They all chain to GHSA-qx2v-qp2m-jg93 (postcss < 8.5.10), pinned inside next@16.2.9 (node_modules/next/node_modules/postcss@8.4.31). Even the latest stable Next still ships it; only the 16.3 canary bumps past it. Your top-level postcss (8.5.x) is fine, and this is build-time-only for a static export. No action needed — just bump next once a stable release ships postcss ≥ 8.5.10.
| const websiteRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); | ||
| const docsRoot = resolve(websiteRoot, docsDir); | ||
| const outRoot = join(websiteRoot, 'content', 'docs'); | ||
| const gitBranch = 'main'; |
There was a problem hiding this comment.
[nit] gitBranch/gitBlobBase duplicate gitConfig in website/lib/shared.ts.
The values currently agree, but a repo rename or branch change has to be made in two places or the sync script's GitHub-fallback links drift from the site's other GitHub links. Since this .mjs can't import the .ts, consider moving the repo/branch constants into a small shared .mjs module both can import — or at least add cross-referencing comments.
| export const revalidate = false; | ||
|
|
||
| export function GET() { | ||
| return new Response(llms(source).index()); |
There was a problem hiding this comment.
[nit] llms.txt (and llms-full.txt) emit root-relative links, not absolute URLs.
The built out/llms.txt contains links like [Installation](/docs/installation) — an LLM or crawler fetching the file in isolation can't resolve those without knowing the origin. The sitemap and robots.txt get this right (absolute URLs from siteUrl).
Suggest prefixing with the site base URL here and in llms-full.txt/route.ts so all three machine-readable outputs are consistent.
| // CI runs where the variable is unset or empty (an empty string would otherwise | ||
| // crash `new URL()` at build time). | ||
| export const siteUrl = | ||
| process.env.NEXT_PUBLIC_SITE_URL || 'https://openspec.dev'; |
There was a problem hiding this comment.
[note] Mind the fallback before first deploy: unset DOCS_SITE_URL → absolute URLs point at a domain serving a different site.
If the workflow deploys before the DOCS_SITE_URL repo variable is set (it's optional), the site is served from *.pages.dev but its sitemap.xml, robots.txt, and OG image URLs will all point at openspec.dev — which currently serves the separate Astro landing page, where those paths 404. The mechanism itself is correct; this is a deploy-ordering footgun worth a line in the README's setup checklist. (Ties into the two-landing-pages decision the PR description already flags.)
|
|
||
| ## One rule: OpenSpec doesn't touch git | ||
|
|
||
| OpenSpec reads and writes plain Markdown under `openspec/`. It never commits, branches, pushes, or pulls — same as it never does for a [store](stores-beta/user-guide.md). That means: |
There was a problem hiding this comment.
[fix] Slight overstatement: openspec store create does commit by default.
Store creation runs git init plus an initial commit (src/commands/store.ts --init-git, default on; src/core/store/git.ts describes “setup-time git init plus one initial commit” as the entire write surface). The stores guide is deliberately narrower (“never clones, syncs, or pushes anything on its own”) — it omits “commits” for exactly this reason.
| OpenSpec reads and writes plain Markdown under `openspec/`. It never commits, branches, pushes, or pulls — same as it never does for a [store](stores-beta/user-guide.md). That means: | |
| OpenSpec reads and writes plain Markdown under `openspec/`. It never commits, branches, pushes, or pulls in your project — and it never clones or syncs a [store](stores-beta/user-guide.md) on its own. That means: |
| Ship your first change in five minutes | ||
| </h2> | ||
| <p className="mx-auto mt-4 max-w-xl text-fd-muted-foreground"> | ||
| Works with 30+ AI assistants — Claude Code, Cursor, Codex, Windsurf, |
There was a problem hiding this comment.
[note] “30+” is right (well — exactly 30), but it exposes a stale “20+” in the root README.
src/core/config.ts has exactly 30 tools with available: true, and the ToolStrip's “15 + 15 more” arithmetic checks out. But README.md still says “works with 20+ AI assistants”, so the two now disagree. Worth bumping the README in this PR while you're touching it — and consider “30” over “30+” since the count is exactly 30.
| @@ -0,0 +1,35 @@ | |||
| { | |||
There was a problem hiding this comment.
[fix] Please switch website/ to pnpm for consistency with the rest of the repo.
The main repo is pnpm (ci.yml runs pnpm install --frozen-lockfile against the root pnpm-lock.yaml), but this package introduces npm + a package-lock.json. One package manager per repo keeps contributor muscle memory and tooling simple. Concretely:
- Replace
website/package-lock.jsonwith awebsite/pnpm-lock.yaml(cd website && pnpm import && rm package-lock.json, or just delete the lockfile andpnpm install). - In
.github/workflows/deploy-docs.yml: addpnpm/action-setup@v4(same asci.yml), switchsetup-nodetocache: pnpmwithcache-dependency-path: website/pnpm-lock.yaml, and changenpm ci→pnpm install --frozen-lockfile. - Update the
npm run ...commands inwebsite/README.mdaccordingly.
Please don't add a pnpm-workspace.yaml — keeping website/ a standalone package (as you have it) is right; this is only about which package manager it uses.
Maintainer review (TabishB) + Alfred blocker: - deploy-docs.yml: guard the Cloudflare deploy on `github.ref == refs/heads/main`. A `workflow_dispatch` on a feature branch previously passed the guard and, since wrangler hardcodes `--branch=main` (a production deploy), would overwrite the live docs site. Non-main dispatches are now build-only. Also resolves Alfred's deploy-path blocker. - package.json: drop the direct `cnfast` dependency and delete the dead `lib/cn.ts` (nothing imports it; a class-merge helper isn't used). - package.json: declare `zod` (^4.4.3) — it was a phantom dep only resolving via fumadocs-mdx's hoisted copy. Refresh the lockfile. - docs page: omit the on-page <DocsDescription>. The frontmatter description is derived from the first body paragraph, so it rendered the intro twice on every page. Kept in generateMetadata for SEO/OG. - team-workflow.md: `openspec store create` does an initial commit, so scope "never commits" to the user's project and reframe the store clause as "never clones or syncs on its own." - README.md: bump stale "20+ AI assistants" to "30+" to match the site. Verified: npm run types:check + npm run build pass, 26 docs synced, intro paragraph now renders once per page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per maintainer review (TabishB): the root repo is pnpm (ci.yml runs `pnpm install --frozen-lockfile` against a v9 `pnpm-lock.yaml`), but `website/` had introduced npm + a `package-lock.json`. Standardize on one package manager: - Replace website/package-lock.json with website/pnpm-lock.yaml (lockfileVersion 9.0, generated with pnpm v9 to match root). - deploy-docs.yml: add pnpm/action-setup@v4 (version 9, before setup-node, as in ci.yml), switch setup-node to `cache: pnpm` / `cache-dependency-path: website/pnpm-lock.yaml`, and `npm ci` → `pnpm install --frozen-lockfile`, `npm run build` → `pnpm run build`. - package.json scripts + README: `npm run ...` → `pnpm run ...`. website/ stays a standalone package (no pnpm-workspace.yaml), as before. Verified: `pnpm install --frozen-lockfile`, `pnpm run build`, and `pnpm run types:check` all pass — 26 docs synced, 87/87 static pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@clay-good Keen to get this merged in, I'll comment out the deploy for now so I can setup the cloudflare config on my end, so that dosen't block this PR. |
alfred-openspec
left a comment
There was a problem hiding this comment.
Re-approving after latest changes. CI is green, deploy remains build-only until Cloudflare setup is ready, and the package-manager cleanup now consistently uses pnpm for the website.
What this adds
A documentation + marketing website for OpenSpec, at
website/, built with Fumadocs and deployed as a static site to Cloudflare Pages. It also adds three new guides todocs/for new users.The problem it solves
OpenSpec's docs live as Markdown in
docs/. There was no browsable, searchable home for them, and any separate site would drift from the source the moment someone edited a doc. This site fixes both: it's a real docs site, and it stays current on its own.How it stays current (no manual updates)
The site's doc pages are generated from
docs/*.md— that folder is the single source of truth. Every build re-mirrors the docs, so:docs/*.md→ the site updates on the next build. Nothing to copy by hand.mainrebuilds and redeploys to Cloudflare, so the published site can't fall behind the docs.Only the marketing landing page is hand-authored; everything under
/docsmirrors automatically.New docs for new users (in
docs/, so they appear on the site too)The pipeline is ready but stays dormant until three steps are done (full instructions in
website/README.md):openspec-docs(production branchmain).CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID.main(GitHub Actions only runs the deploy triggers frommain).Until then, docs still mirror correctly on every build — they just don't reach Cloudflare on their own.
Note: the existing landing page
openspec.dev today is a separate Astro site. This PR ships its own Fumadocs landing page. Whether to keep it, port the Astro one into it, or serve only
/docsis a maintainer decision — nothing else in the pipeline depends on it.Scope
website/(its ownpackage.json/lockfile); not wired into the CLI build/test, so the published package is unaffected.website/: the three newdocs/*.mdguides (plus light cross-links in existing docs), the.github/workflows/deploy-docs.ymlworkflow, and a "Why teams adopt OpenSpec" section in the rootREADME.md.🤖 Generated with Claude Code