Restructure website for dual-product support#17
Conversation
- Changed title from 'Lovable App' to 'KDM Ecosystem' - Updated description to ecosystem-neutral content - Removed 'author: Lovable' meta tag - Updated OG/twitter metadata to KDM Ecosystem - Removed twitter:site @lovable reference
…g types - ProductFeature with icon (string), title, desc, cmd - ProductCommand with name, sig, desc, output - ProductStat with value, label - TerminalLine with optional prompt, out, blink - ProductMetadata for SEO/OG fields - ProductConfig combining all of the above
- Full ProductConfig with exact content from existing components - 6 features with Lucide icon names, 4 commands, 3 stats - 9 terminal lines matching Terminal.tsx - Metadata for SEO, CTA content, copyright
- Full ProductConfig with Docker Guard branding - 6 features (Shield, Eye, HeartPulse, Radio, ScrollText, Cloud) - 4 commands (guard, ps, health, events) with terminal output - 3 stats for container monitoring - 10 terminal lines with dg commands and output
- products array with kdm and dockerGuard configs - getProductBySlug lookup function - defaultProduct fallback export (kdm)
- 00-01-SUMMARY.md: root metadata fix results - 01-01-SUMMARY.md: product config system results - ROADMAP.md: mark both Wave 1 plans as complete
…seProduct hook - ProductProvider accepts optional slug prop, validates against registry - useProduct hook returns current ProductConfig (never undefined) - Falls back to default product (kdm) when slug is missing or unknown
- Wrap Outlet in ProductProvider in RootComponent - Default product (kdm) is used until route-specific layouts pass a slug
- 01-02-SUMMARY.md with execution details and Wave 3 guidance - ROADMAP.md: mark 01-02 as completed
- Replaced hardcoded 'kdm' brand name with product.brandName
- Replaced /docs Link with dynamic <a href={product.docsPath}>
- Replaced hardcoded GitHub URLs with product.githubUrl
- Both desktop and mobile Sheet docs/GitHub links are now product-aware
- Added import * as LucideIcons for dynamic icon resolution
- Added useProduct hook to consume product config
- Removed hardcoded features array
- Features grid now driven by product.features from ProductContext
- Dynamic heading Built for {product.displayName}
- Icons resolved from string names via LucideIcons lookup
- Replaced hardcoded 'kdm' brand text with product.brandName - Replaced hardcoded copyright with product.copyright - Replaced hardcoded GitHub URLs with product.githubUrl (Status + GitHub links) - Privacy and Terms links remain root-level unchanged
…hook - Add useProduct import from ProductContext - Replace hardcoded version badge with product.version - Replace hardcoded headline with product.displayName - Replace hardcoded tagline with product.tagline - Replace hardcoded description with product.description - Replace hardcoded install command with product.installCommand - Replace hardcoded stats grid with product.stats.map() - Replace hardcoded CTA button with product.ctaPrimaryText - Replace hardcoded GitHub URL with product.githubUrl
- Added useProduct hook to consume product config
- Removed hardcoded commands array
- Command tabs now driven by product.commands from ProductContext
- Dynamic heading {product.displayName} commands
- All existing layout, tab UI, and terminal output styling preserved
…uct hook - Add useProduct import from ProductContext - Remove hardcoded module-level lines array - Replace hardcoded terminal lines with product.terminalLines - Replace timer setup to iterate over product.terminalLines - Replace hardcoded title with product.brandName
- Navbar: brandName, docsPath, githubUrl now from ProductContext - Footer: brandName, copyright, githubUrl now from ProductContext - Updated ROADMAP.md to mark Phase 3 complete
- Added useProduct hook to consume product config - Replaced hardcoded Ship. with product.ctaTagline - Replaced hardcoded description with product.ctaDescription - Replaced Start Now button with product.ctaPrimaryText - Replaced Link to /docs with <a> using product.docsPath - Removed unused @tanstack/react-router Link import - All existing layout, CSS classes, and responsive sizing preserved
…plan - Add SUMMARY.md documenting all changes - Update ROADMAP.md to mark 04a-01 plan as complete
- Added SUMMARY.md documenting all changes, decisions, and deviations - Created STATE.md tracking execution position and accumulated decisions - Updated ROADMAP.md marking 04b-01 as completed
- Replace single-product KDM landing page with hub page at / - Show both KDM and Docker Guard product cards with stats - Inline footer with links to /privacy and /terms - Remove imports of Navbar, Hero, Features, Commands, CTA, Footer - HubPage component renders selection gateway
- kdm.tsx: layout route at /kdm with ProductProvider slug='kdm' - docker-guard.tsx: layout route at /docker-guard with ProductProvider slug='docker-guard' - Both routes wrap children in correct ProductContext - TanStack Router auto-registers both routes in generated tree
- unenv is a transitive dependency needed by nitro build - docs/ added to gitignore (build output directory)
- SUMMARY.md created with execution details - STATE.md updated with completed plan and session info - ROADMAP.md marks 02a-01 as completed
- src/routes/kdm.index.tsx — kdm landing page with Navbar, Hero, Features, Commands, CTA, Footer - src/routes/docker-guard.index.tsx — Docker Guard landing page with same structure - Both pages render inside the product layout Outlets created in 02a-01 - Head metadata sourced from product config for proper OG tags
- SUMMARY.md documenting all changes - STATE.md updated with completion status and plan tracking - ROADMAP.md updated with 02a-02 marked complete
… doc loader - Create src/docs/kdm/ with kdm-cli documentation files - Create src/docs/docker-guard/ with Docker Guard documentation files - Remove old flat doc files from src/docs/ - Refactor src/lib/docs.ts: add createDocLoader(product) factory function - Update all 6 product doc route files to use createDocLoader - Fix .gitignore to only ignore root-level docs/ not src/docs/
…ting through unknown The cast from typeof LucideIcons to Record<string, ComponentType<...>> failed because lucide-react icons use ForwardRefExoticComponent which isn't directly assignable to ComponentType. Fixed by casting through unknown first.
- Hero primary CTA: href='#' → product.docsPath - CTA section primary CTA: href='#' → product.githubUrl - Footer 'Status' → 'Issues' linking to GitHub issues page
- Added .planning/ and REVIEW-FIX.md to .gitignore - Removed 21 planning artifacts and 1 review artifact from tracking
|
@Yuvraj-Sarathe is attempting to deploy a commit to the utkarsh232005's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Warning Review limit reached
More reviews will be available in 21 minutes and 4 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (24)
📝 WalkthroughWalkthroughThis PR migrates the KDM website from a single hardcoded product to a configurable multi-product ecosystem. A new product configuration system, React context provider, and parameterized doc loader enable dynamic product-specific rendering. Routes reorganize under product paths (/kdm, /docker-guard), components consume product context, and the home page becomes an ecosystem hub. ChangesMulti-product ecosystem refactor
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
- Removed package-lock.json from .gitignore (was blocking npm ci in CI) - Added bun.lock to .gitignore (project uses npm) - CI runs npm ci which requires a lockfile — bun.lock is not compatible
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/kdm.docs.index.tsx (1)
5-23:⚠️ Potential issue | 🟠 Major | ⚡ Quick winSanitize
markedHTML before rendering to prevent XSS
src/lib/docs.tssetshtml: marked.parse(body, ...)andsrc/components/docs/DocView.tsxrenders it viadangerouslySetInnerHTML;markeddoesn’t sanitize raw HTML by default, so any HTML in the markdown will execute in the browser. Sanitize the HTML (e.g., DOMPurify) in the loader (centralized for both/kdm/docs/and/kdm/docs/$slug) before settingdoc.html.🤖 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 `@src/routes/kdm.docs.index.tsx` around lines 5 - 23, The generated HTML from marked in the docs loader (created by createDocLoader and returned via getDoc) is not being sanitized before being stored/served, so update the loader logic in the function that assigns doc.html (the code in src/lib/docs.ts used by createDocLoader) to run the marked.parse output through a sanitizer (e.g., DOMPurify) before setting doc.html; ensure the sanitized HTML is what KdmDocsIndex (which calls getDoc("")) and the DocView component receive and render via dangerouslySetInnerHTML so raw HTML cannot execute in the browser.
🧹 Nitpick comments (6)
src/config/products/types.ts (1)
44-47: ⚡ Quick winMark config collections as readonly.
These product configs are effectively shared singletons. Mutable arrays keep accidental in-place edits type-safe today, which would leak across every subtree consuming the same context value.
Proposed direction
export interface ProductConfig { slug: ProductSlug; displayName: string; brandName: string; tagline: string; description: string; version: string; installCommand: string; githubUrl: string; docsPath: string; - features: ProductFeature[]; - commands: ProductCommand[]; - stats: ProductStat[]; - terminalLines: TerminalLine[]; + readonly features: readonly ProductFeature[]; + readonly commands: readonly ProductCommand[]; + readonly stats: readonly ProductStat[]; + readonly terminalLines: readonly TerminalLine[]; ctaTagline: string; ctaDescription: string; ctaPrimaryText: string; metadata: ProductMetadata; copyright: string;Also applies to: 34-53
🤖 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 `@src/config/products/types.ts` around lines 44 - 47, The product config exposes mutable arrays (features, commands, stats, terminalLines and other collection properties in the same block around lines 34–53) which allows in-place edits to leak across consumers; change those types to readonly collections (e.g. use readonly ProductFeature[] or ReadonlyArray<ProductFeature> for features, readonly ProductCommand[] for commands, readonly ProductStat[] for stats, readonly TerminalLine[] for terminalLines, and likewise replace any other mutable array types in that interface/type) so the config is treated as an immutable/shared singleton; update the exported type declarations in src/config/products/types.ts accordingly.src/context/ProductContext.tsx (1)
13-19: ⚡ Quick winFix Prettier formatting.
Static analysis detected formatting inconsistencies. Run Prettier to align the code with the project's formatting rules.
npx prettier --write src/context/ProductContext.tsxAlso applies to: 21-23
🤖 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 `@src/context/ProductContext.tsx` around lines 13 - 19, The ProductProvider component signature has Prettier formatting inconsistencies; run the project's Prettier formatter (e.g., npx prettier --write) on the file and reformat the function declaration around ProductProvider and the adjacent prop/type lines (the slug?: string; children: ReactNode; block) so they match project style; ensure consistent spacing, commas, and braces to resolve the static analysis warnings.src/config/products/docker-guard.ts (1)
50-50: 💤 Low valueClarify the "cloud · auto" command pattern.
The
cmdvalue"cloud · auto"at line 50 differs from the CLI command patterns used elsewhere (e.g.,"dg guard","dg ps"). If this indicates a feature not yet exposed via CLI or requires special UI rendering, consider adding a comment or adjusting the value to match the established pattern for consistency.🤖 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 `@src/config/products/docker-guard.ts` at line 50, The cmd value "cloud · auto" in the product config (the cmd property for the Docker-guard product) is inconsistent with other CLI patterns like "dg guard" and "dg ps" — either replace it with the canonical CLI token (e.g., "dg cloud" or "dg auto" per product behavior) or add an inline comment next to the cmd property explaining that this is a UI-only display string and not a real CLI command; update the cmd property in the same object where cmd is defined (look for the Docker-guard product entry) and ensure any consumer expecting CLI tokens uses the canonical token instead of the current display string.src/config/products/index.ts (1)
6-8: ⚡ Quick winAdd explicit return type annotation.
The
getProductBySlugfunction implicitly returnsProductConfig | undefined, but an explicit annotation improves type clarity and prevents accidental type widening.📘 Proposed fix
+import type { ProductConfig } from "./types"; + -export function getProductBySlug(slug: string) { +export function getProductBySlug(slug: string): ProductConfig | undefined { return products.find((p) => p.slug === slug); }🤖 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 `@src/config/products/index.ts` around lines 6 - 8, Add an explicit return type to getProductBySlug: change its signature to return ProductConfig | undefined so the function getProductBySlug(slug: string): ProductConfig | undefined { ... } is explicit; locate the function in src/config/products/index.ts and annotate the return type using the existing ProductConfig type (import it if necessary).src/components/Terminal.tsx (1)
8-13: ⚡ Quick winRerun the animation when
product.terminalLineschanges.This effect closes over
product.terminalLines, but the empty dependency array means the typewriter sequence won't restart if the product context changes. Resetvisibleand include a stable product/lines dependency so the terminal stays in sync with the selected product.Suggested fix
useEffect(() => { + setVisible(0); const timers = product.terminalLines.map((_, i) => setTimeout(() => setVisible((v) => Math.max(v, i + 1)), 300 + i * 280) ); return () => timers.forEach(clearTimeout); - }, []); + }, [product.terminalLines]);🤖 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 `@src/components/Terminal.tsx` around lines 8 - 13, The effect in useEffect that schedules timeouts for product.terminalLines currently has an empty dependency array so it won’t restart when product.terminalLines changes; update the effect that creates timers (the useEffect block referencing product.terminalLines, timers, setVisible) to depend on the lines (e.g., product.terminalLines or a stable key like product.id or serialized lines) and inside the effect reset visible to 0 (or the initial value) before scheduling, clear any existing timeouts in the cleanup, and then schedule new timeouts so the typewriter sequence restarts whenever the product/lines change.src/components/Commands.tsx (1)
5-7: ⚡ Quick winDowngrade: no current crash path, but add a defensive guard
In this app,
src/components/Commands.tsxis mounted under route-levelProductProviderinstances with a fixedslug(/kdmor/docker-guard), andactiveis only set from the currentproduct.commands.map((_, i) => ...)indices—soproduct.commands[active]should be defined with the current config. Still, a small guard (and optional clamping ifProductContextever becomes dynamic orcommandscan be empty) would prevent future render-time crashes when configs change.🤖 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 `@src/components/Commands.tsx` around lines 5 - 7, The code directly indexes product.commands with product.commands[active] (variables: active, setActive, useProduct, product, product.commands, cmd) which can crash if commands is empty or active is out of range; add a defensive guard: ensure product.commands exists and has length > 0 before indexing, clamp active to [0, product.commands.length - 1] (or default to 0), and compute cmd only when safe (e.g., const cmd = product.commands?.[clampedActive] ?? undefined) so renders won't throw if the product context changes or commands becomes empty.
🤖 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 `@package.json`:
- Line 67: The package.json currently lists the prerelease "unenv"
(^2.0.0-rc.24) as a production dependency but there’s no usage in source; either
move "unenv" to devDependencies if it’s only build/test/tooling, remove it
entirely if unused, or pin it to the stable release ("unenv" 1.10.0) if you
truly need it in production; locate the "unenv" entry in package.json and update
the dependency section accordingly and confirm no runtime imports reference
unenv before changing.
In `@src/components/CTA.tsx`:
- Around line 19-21: The CTA component currently uses a plain <a> to navigate to
product.docsPath which prevents TanStack Router client-side transitions; replace
the anchor with the TanStack Router <Link> (import { Link } from
'`@tanstack/router`') and render <Link to={product.docsPath} className="btn-mono
...">Read the docs</Link>, keeping the same className and children; if
product.docsPath can be external (startsWith 'http'), add a small conditional to
fall back to an <a> with target/_blank, otherwise use <Link> for internal
routing.
In `@src/components/Features.tsx`:
- Around line 1-2: The code currently namespace-imports all icons as LucideIcons
and uses runtime lookup LucideIcons[f.icon] in Features.tsx which prevents
tree-shaking and increases bundle size; replace that pattern by either creating
a small explicit registry mapping the expected icon names (the f.icon values) to
individually imported icon components and use that map in the Icon selection, or
import Lucide’s dynamic renderer (DynamicIcon from "lucide-react/dynamic") and
pass the f.icon name to it; update the Icon lookup logic to use the registry key
or DynamicIcon instead of LucideIcons[f.icon] and remove the namespace import to
ensure per-icon imports are tree-shakeable.
In `@src/components/Hero.tsx`:
- Around line 9-12: The copy handler currently calls
navigator.clipboard.writeText(product.installCommand) without awaiting or
handling rejection and sets setCopied(true) immediately; change the copy
function (copy) to await or use .then/.catch on navigator.clipboard.writeText
and only call setCopied(true) after the writeText promise resolves, handle
errors in the .catch (e.g., set an error state or log via console.error) and
ensure you don't leave an unhandled rejection; also if the click handler is a
prop, make it async or return the promise so the component's event flow remains
correct.
In `@src/components/Navbar.tsx`:
- Line 25: The desktop and mobile "Docs" anchors using product.docsPath are
internal TanStack Router routes and cause full page reloads; in Navbar (replace
the <a href={product.docsPath}> instances including the mobile variant), and
likewise in Hero and CTA where product.docsPath is used, swap the anchor tags
for the TanStack Router Link component and use the to={product.docsPath} prop so
navigation is SPA-friendly; ensure you import Link from the router at the top of
each component (e.g., Navbar, Hero, CTA) and preserve existing className and
children when replacing the tag.
In `@src/config/products/types.ts`:
- Around line 34-43: Replace the plain string for ProductConfig.slug with a
shared literal union type: define and export a single source of truth (e.g., a
const array like PRODUCT_SLUGS = ['foo','bar'] as const and a type ProductSlug =
typeof PRODUCT_SLUGS[number] or an exported enum) in this module, change the
interface to use slug: ProductSlug, and update all other modules that currently
accept or construct slug values to import and use ProductSlug (or PRODUCT_SLUGS)
so typos fail at compile time rather than runtime; keep the symbol
ProductConfig.slug as the consumer-facing property name.
In `@src/context/ProductContext.tsx`:
- Around line 13-24: ProductProvider currently calls resolveConfig(slug) on
every render which creates a new config object and may trigger unnecessary
re-renders of consumers; wrap the resolveConfig(slug) call in React.useMemo so
the config is recomputed only when slug changes, keeping the same reference
across renders, e.g. memoize the value used for ProductContext.Provider (the
resolved config passed into ProductContext.Provider) and list slug as the
dependency.
In `@src/lib/docs.ts`:
- Around line 49-59: The frontmatter "order" parsing uses Number(data.order)
which can yield NaN and break the sort in the .sort comparator; update the
mapping where parseFrontmatter is used (the object with slug, title, order,
html) to coerce and validate the order value (e.g., use Number(data.order) only
if Number.isFinite(...) or fallback to 999) so that the order property on each
doc is always a finite number, keeping parseFrontmatter/data.order handling
robust and preserving the existing sort call that uses a.order - b.order ||
a.title.localeCompare(b.title).
In `@src/routes/index.tsx`:
- Around line 68-70: Prettier wants the JSX props and inline text condensed onto
single lines; update the paragraph and similar blocks so the element and its
text are on one line (e.g., change <p className="text-sm text-foreground/50">
Choose your tool </p> to <p className="text-sm text-foreground/50">Choose your
tool</p>) and apply the same single-line formatting to the other affected JSX
blocks around the code that spans lines 84-95.
- Around line 42-44: Prettier wants the JSX text content on a single line:
collapse the multiline <p> element that renders product.description into a
single-line JSX expression by keeping the same className and content but placing
the opening tag, the {product.description} expression, and the closing tag on
one line (locate the JSX that uses product.description in the <p
className="text-sm text-foreground/50 mb-6 leading-relaxed"> element and
reformat it to a single line).
- Line 56: The current array destructuring "const [kdmProduct,
dockerGuardProduct] = products" is fragile; replace it with explicit lookups
(e.g., find product where product.slug === 'kdm' and product.slug ===
'docker-guard') so the mapping is explicit and order-independent, assign those
results to kdmProduct and dockerGuardProduct, and add a fail-fast check (throw
or processLogger/error) if either lookup returns undefined so the page fails
loudly when a product is missing.
---
Outside diff comments:
In `@src/routes/kdm.docs.index.tsx`:
- Around line 5-23: The generated HTML from marked in the docs loader (created
by createDocLoader and returned via getDoc) is not being sanitized before being
stored/served, so update the loader logic in the function that assigns doc.html
(the code in src/lib/docs.ts used by createDocLoader) to run the marked.parse
output through a sanitizer (e.g., DOMPurify) before setting doc.html; ensure the
sanitized HTML is what KdmDocsIndex (which calls getDoc("")) and the DocView
component receive and render via dangerouslySetInnerHTML so raw HTML cannot
execute in the browser.
---
Nitpick comments:
In `@src/components/Commands.tsx`:
- Around line 5-7: The code directly indexes product.commands with
product.commands[active] (variables: active, setActive, useProduct, product,
product.commands, cmd) which can crash if commands is empty or active is out of
range; add a defensive guard: ensure product.commands exists and has length > 0
before indexing, clamp active to [0, product.commands.length - 1] (or default to
0), and compute cmd only when safe (e.g., const cmd =
product.commands?.[clampedActive] ?? undefined) so renders won't throw if the
product context changes or commands becomes empty.
In `@src/components/Terminal.tsx`:
- Around line 8-13: The effect in useEffect that schedules timeouts for
product.terminalLines currently has an empty dependency array so it won’t
restart when product.terminalLines changes; update the effect that creates
timers (the useEffect block referencing product.terminalLines, timers,
setVisible) to depend on the lines (e.g., product.terminalLines or a stable key
like product.id or serialized lines) and inside the effect reset visible to 0
(or the initial value) before scheduling, clear any existing timeouts in the
cleanup, and then schedule new timeouts so the typewriter sequence restarts
whenever the product/lines change.
In `@src/config/products/docker-guard.ts`:
- Line 50: The cmd value "cloud · auto" in the product config (the cmd property
for the Docker-guard product) is inconsistent with other CLI patterns like "dg
guard" and "dg ps" — either replace it with the canonical CLI token (e.g., "dg
cloud" or "dg auto" per product behavior) or add an inline comment next to the
cmd property explaining that this is a UI-only display string and not a real CLI
command; update the cmd property in the same object where cmd is defined (look
for the Docker-guard product entry) and ensure any consumer expecting CLI tokens
uses the canonical token instead of the current display string.
In `@src/config/products/index.ts`:
- Around line 6-8: Add an explicit return type to getProductBySlug: change its
signature to return ProductConfig | undefined so the function
getProductBySlug(slug: string): ProductConfig | undefined { ... } is explicit;
locate the function in src/config/products/index.ts and annotate the return type
using the existing ProductConfig type (import it if necessary).
In `@src/config/products/types.ts`:
- Around line 44-47: The product config exposes mutable arrays (features,
commands, stats, terminalLines and other collection properties in the same block
around lines 34–53) which allows in-place edits to leak across consumers; change
those types to readonly collections (e.g. use readonly ProductFeature[] or
ReadonlyArray<ProductFeature> for features, readonly ProductCommand[] for
commands, readonly ProductStat[] for stats, readonly TerminalLine[] for
terminalLines, and likewise replace any other mutable array types in that
interface/type) so the config is treated as an immutable/shared singleton;
update the exported type declarations in src/config/products/types.ts
accordingly.
In `@src/context/ProductContext.tsx`:
- Around line 13-19: The ProductProvider component signature has Prettier
formatting inconsistencies; run the project's Prettier formatter (e.g., npx
prettier --write) on the file and reformat the function declaration around
ProductProvider and the adjacent prop/type lines (the slug?: string; children:
ReactNode; block) so they match project style; ensure consistent spacing,
commas, and braces to resolve the static analysis warnings.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3014d05f-7c0e-4392-b0cf-7cacdea34f34
⛔ Files ignored due to path filters (1)
src/assets/docker-guard-logo.pngis excluded by!**/*.png
📒 Files selected for processing (35)
.gitignorepackage.jsonsrc/components/CTA.tsxsrc/components/Commands.tsxsrc/components/Features.tsxsrc/components/Footer.tsxsrc/components/Hero.tsxsrc/components/Navbar.tsxsrc/components/Terminal.tsxsrc/config/products/docker-guard.tssrc/config/products/index.tssrc/config/products/kdm.tssrc/config/products/types.tssrc/context/ProductContext.tsxsrc/docs/docker-guard/commands.mdsrc/docs/docker-guard/index.mdsrc/docs/docker-guard/installation.mdsrc/docs/kdm/commands.mdsrc/docs/kdm/contributing.mdsrc/docs/kdm/index.mdsrc/docs/kdm/installation.mdsrc/lib/docs.tssrc/routeTree.gen.tssrc/routes/__root.tsxsrc/routes/docker-guard.docs.$slug.tsxsrc/routes/docker-guard.docs.index.tsxsrc/routes/docker-guard.docs.tsxsrc/routes/docker-guard.index.tsxsrc/routes/docker-guard.tsxsrc/routes/index.tsxsrc/routes/kdm.docs.$slug.tsxsrc/routes/kdm.docs.index.tsxsrc/routes/kdm.docs.tsxsrc/routes/kdm.index.tsxsrc/routes/kdm.tsx
- unstorage (dep of @lovable.dev/vite-tanstack-config) has lru-cache@^11.2.6 as optional peer - npm 11 (local) skips optional peers in lockfile, but npm 10 (CI on Node.js 20) requires them - Adding lru-cache directly as optionalDependency ensures lockfile parity
- Auto-fixed by Prettier 3.7.3 - Addresses CI lint failure: improper line breaks, indentation, quotes, whitespace in JSX
There was a problem hiding this comment.
Our agent can fix these. Install it.
Gates Passed
3 Quality Gates Passed
Absence of Expected Change Pattern
- kdm-website/src/components/Hero.tsx is usually changed with: kdm-website/vite.config.ts
Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
|
The one test this PR is failing has been addressed in #18 So merge this PR @utkarsh232005 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Hey @Yuvraj-Sarathe, thanks for the effort on this restructuring! Right now, this changes the root route ( Instead of an ecosystem hub at the root, let's integrate the new products directly into the existing Navbar using a dropdown menu (e.g., "Products" or "Tools"). When a user clicks it, they should see the other tools listed—like KDC—and clicking a tool will redirect them to its respective webpage. |
so what to do with this PR? |
you can close this pr and create fresh pr with the required changes |
I don't think I can spare time for such task now because my college is restarting from tomorrow so please assign someone else |
Issue #14
Description
The website was originally built as a single-product site for KDM CLI only. This restructures the codebase to support multiple products under a shared ecosystem, starting with KDM CLI and Docker Guard. The architecture moves from hardcoded product content to a config-driven system, reorganizes routing around product hubs, and introduces a React context for dynamic branding across all shared components.
Changes:
Config System (
src/config/products/)types.ts):ProductConfig, ProductFeature, ProductCommand, ProductStat, TerminalLine, ProductMetadatakdm.ts) and Docker Guard (docker-guard.ts) covering branding, features, commands, stats, and terminal demo contentindex.ts) withgetProductBySlug()resolver and default product fallbackProduct Context (
src/context/ProductContext.tsx)useProduct()hook for any component to access current product config__root.tsxat the top level with slug derived from route matching Routing (src/routes/)index.tsxfrom KDM landing page to a product-selection hubkdm.tsx, docker-guard.tsx) that provide product context for each sub-treekdm.docs.tsx, kdm.docs.index.tsx, kdm.docs.$slug.tsxand equivalent for Docker Guarddocs.tsx, docs.index.tsx, docs.$slug.tsxin favor of namespaced variantsComponents (
src/components/)useProduct()for dynamic, config-driven contenthref="#") and corrected footer "Status" link targetDocumentation
(src/docs/)src/docs/kdm/subdirectorysrc/docs/docker-guard/with placeholder filessrc/lib/docs.tsintocreateDocLoader(product)factory functionRoute Map
/(KDM landing)/(product hub)/kdm//docs/kdm/docs/docs/:slug/kdm/docs/:slug/docker-guard//docker-guard/docs/docker-guard/docs/:slugRemaining Work:
Summary by CodeRabbit
New Features
Documentation
Chores