From 4bc9f73f0746d9897820234eb697ee378faf816e Mon Sep 17 00:00:00 2001 From: Mohammed Khan Date: Tue, 8 Jul 2025 17:24:04 +0530 Subject: [PATCH 1/7] docs: convert introduction to MDX and add React components for better UI --- .../{introduction.md => introduction.mdx} | 125 +++++++++++++----- .../FeatureList/FeatureList.module.css | 43 ++++++ src/components/FeatureList/FeatureList.tsx | 24 ++++ src/components/FeatureList/index.ts | 1 + src/components/InfoBox/InfoBox.module.css | 19 +++ src/components/InfoBox/InfoBox.tsx | 15 +++ src/components/InfoBox/index.ts | 1 + .../PlatformCard/PlatformCard.module.css | 18 +++ src/components/PlatformCard/PlatformCard.tsx | 23 ++++ src/components/PlatformCard/index.ts | 1 + .../PlatformGrid/PlatformGrid.module.css | 6 + src/components/PlatformGrid/PlatformGrid.tsx | 20 +++ src/components/PlatformGrid/index.ts | 1 + src/css/custom.css | 12 ++ static/img/overview/Azure.png | Bin 0 -> 1864 bytes static/img/overview/Bitbucket.png | Bin 0 -> 1468 bytes static/img/overview/Github.png | Bin 0 -> 3020 bytes static/img/overview/Gitlab.png | Bin 0 -> 1780 bytes static/img/overview/Jira.png | Bin 0 -> 1756 bytes static/img/overview/Linear.png | Bin 0 -> 2308 bytes 20 files changed, 275 insertions(+), 34 deletions(-) rename docs/overview/{introduction.md => introduction.mdx} (56%) create mode 100644 src/components/FeatureList/FeatureList.module.css create mode 100644 src/components/FeatureList/FeatureList.tsx create mode 100644 src/components/FeatureList/index.ts create mode 100644 src/components/InfoBox/InfoBox.module.css create mode 100644 src/components/InfoBox/InfoBox.tsx create mode 100644 src/components/InfoBox/index.ts create mode 100644 src/components/PlatformCard/PlatformCard.module.css create mode 100644 src/components/PlatformCard/PlatformCard.tsx create mode 100644 src/components/PlatformCard/index.ts create mode 100644 src/components/PlatformGrid/PlatformGrid.module.css create mode 100644 src/components/PlatformGrid/PlatformGrid.tsx create mode 100644 src/components/PlatformGrid/index.ts create mode 100644 static/img/overview/Azure.png create mode 100644 static/img/overview/Bitbucket.png create mode 100644 static/img/overview/Github.png create mode 100644 static/img/overview/Gitlab.png create mode 100644 static/img/overview/Jira.png create mode 100644 static/img/overview/Linear.png diff --git a/docs/overview/introduction.md b/docs/overview/introduction.mdx similarity index 56% rename from docs/overview/introduction.md rename to docs/overview/introduction.mdx index f937ac67..0af6c14f 100644 --- a/docs/overview/introduction.md +++ b/docs/overview/introduction.mdx @@ -9,6 +9,11 @@ description: slug: "/" --- +import FeatureList from "../../src/components/FeatureList" +import InfoBox from "../../src/components/InfoBox" +import PlatformGrid from "../../src/components/PlatformGrid" +import PlatformCard from "../../src/components/PlatformCard" + # Introduction This page provides a conceptual introduction to CodeRabbit. For a hands-on tutorial, see [Quickstart](/getting-started/quickstart/). @@ -18,21 +23,32 @@ This page provides a conceptual introduction to CodeRabbit. For a hands-on tutor Developers can interact directly with the CodeRabbit bot within their existing Git platform's pull request interface to add context, ask questions, or even have the bot generate code. Over time, CodeRabbit learns from user input and improves its suggestions.
- +
## Core features Core CodeRabbit features include the following: -- Integrates rapidly with popular Git platforms and workflows. -- Applies dozens of open-source, industry-standard code analyzers to every commit. -- Implements code reviews as familiar pull-request comments. -- Works with contributors through natural-language conversation in comments. -- Learns and adapts to your team's code style and review preferences. -- Provides an observability dashboard of code-contribution activity. -- Practices strong privacy and security, with no retention of analyzed code. -- Offers free use for public repositories, and flexible pricing for private codebases. + ## Seamless workflow integration @@ -58,52 +74,93 @@ No matter how you tune and customize CodeRabbit, its default settings make it us CodeRabbit integrates in just a few clicks with many popular Git platforms: -- GitHub, GitHub Enterprise Cloud, GitHub Enterprise Server, -- GitLab, GitLab Self-Managed -- Azure DevOps -- Bitbucket Cloud - -For more information, see [Supported Git Platforms](/platforms/). + + + + + + + + For more information, see Supported Git Platforms. + ### Issue-management integration You can integrate CodeRabbit with issue-management platforms. This lets you ask CodeRabbit to create tickets during code reviews, or chat with CodeRabbit about your code from within issue comments. Compatible platforms include the following: -- GitHub Issues -- GitLab Issues -- Jira -- Linear + + + + + + -For more information, see [Issue Creation](/guides/issue-creation) and [Issue Chat](/guides/issue-chat). + + For more information, see Issue Creation{" "} + and Issue Chat. + ## Data privacy and security CodeRabbit collects only the minimum amount of information needed to provide you with our code review services. Our privacy and security posture centers around protecting your data through ephemerality: -- All queries to large language models (LLMs) exist in-memory only, with zero retention after each query completes. -- We don't use your code, code reviews, or other collected data to train LLMs. -- CodeRabbit doesn't share any collected customer data with third parties. -- We keep all customer data confidential, and isolated by organization. -- Our data collection and storage practices comply with SOC 2 and GDPR standards. - -For more information about how we protect your data, see [the CodeRabbit Trust Center](https://trust.coderabbit.ai). + + + + For more information about how we protect your data, see{" "} + the CodeRabbit Trust Center. + ## Flexible pricing, free for public repositories Public repositories can use the Pro tier of CodeRabbit at no charge, including all of the code-review features described on this page. Rate limits might apply. -For private repositories, a number of pricing tiers are available. These range from a Free tier that offers unlimited code-change summaries, to an Enterprise tier with access to advanced features and SLA support. For more information, see [Pricing](https://www.coderabbit.ai/pricing). +For private repositories, a number of pricing tiers are available. These range from a Free tier that offers unlimited code-change summaries, to an Enterprise tier with access to advanced features and SLA support. + + + For more information, see{" "} + Pricing. + ## Review local changes from within VSCode As a separate, free product, CodeRabbit offers a VSCode extension that brings a subset of core CodeRabbit features to VSCode. This lets you use the power of CodeRabbit to tune and tidy your code changes locally before pushing your changes into a formal pull request for more thorough reviews. -For more information, see [Review local changes](/code-editors). + + For more information, see Review local changes. + ## What's next -- [Quickstart](/getting-started/quickstart/) lets you experience your first CodeRabbit code review first-hand. - -- [Review local changes](/code-editors) guides you through installing and using a subset of CodeRabbit features directly from your code editor. - -- [Why CodeRabbit?](/overview/why-coderabbit) dives further into the philosophies and technologies that drive CodeRabbit. + + Quickstart lets you experience + your first CodeRabbit code review first-hand. + , + <> + Review local changes guides you through + installing and using a subset of CodeRabbit features directly from your + code editor. + , + <> + Why CodeRabbit? dives further into + the philosophies and technologies that drive CodeRabbit. + , + ]} +/> diff --git a/src/components/FeatureList/FeatureList.module.css b/src/components/FeatureList/FeatureList.module.css new file mode 100644 index 00000000..b1beca83 --- /dev/null +++ b/src/components/FeatureList/FeatureList.module.css @@ -0,0 +1,43 @@ +.crFeatureCard { + background: var(--imf-list-card-background-color); + border-radius: 8px; + padding: 1.3rem; + margin: 0.8rem 0; + border: 2px solid var(--ifm-background-color-secondary); +} + +.crFeatureList { + list-style: none; + margin: 0; + padding: 0; +} + +.crFeatureList li { + position: relative; + padding-left: 1.7em; + margin-bottom: 1em; + font-size: 1.08rem; + line-height: 1.6; +} + +.crFeatureList li:before { + content: ""; + position: absolute; + left: 0.3em; + top: 0.5em; + width: 0.6em; + height: 0.6em; + background: var(--imf-list-bullets-color); + border-radius: 50%; + display: inline-block; +} + +.crFeatureList li a { + color: var(--ifm-color-primary, orange); + text-decoration: none; + font-weight: 500; +} + +.crFeatureList li a:hover { + text-decoration: underline; +} diff --git a/src/components/FeatureList/FeatureList.tsx b/src/components/FeatureList/FeatureList.tsx new file mode 100644 index 00000000..2a674bdf --- /dev/null +++ b/src/components/FeatureList/FeatureList.tsx @@ -0,0 +1,24 @@ +import React from "react" +import styles from "./FeatureList.module.css" + +interface FeatureListProps { + items: React.ReactNode[] + className?: string +} + +export const FeatureList: React.FC = ({ + items, + className, +}) => { + return ( +
+
    + {items.map((item, index) => ( +
  • {item}
  • + ))} +
+
+ ) +} + +export default FeatureList diff --git a/src/components/FeatureList/index.ts b/src/components/FeatureList/index.ts new file mode 100644 index 00000000..3c506661 --- /dev/null +++ b/src/components/FeatureList/index.ts @@ -0,0 +1 @@ +export { FeatureList, default } from "./FeatureList" diff --git a/src/components/InfoBox/InfoBox.module.css b/src/components/InfoBox/InfoBox.module.css new file mode 100644 index 00000000..afa9212b --- /dev/null +++ b/src/components/InfoBox/InfoBox.module.css @@ -0,0 +1,19 @@ +.infoBox { + border: 2px solid var(--imf-color-border-orange); + border-radius: 12px; + background: var(--imf-color-background-orange-light); + padding: 0.7em; +} + +.infoBox p { + margin: 0rem; +} + +.infoBox a { + color: var(--ifm-color-primary); + text-decoration: none; +} + +.infoBox a:hover { + text-decoration: underline; +} diff --git a/src/components/InfoBox/InfoBox.tsx b/src/components/InfoBox/InfoBox.tsx new file mode 100644 index 00000000..988d193f --- /dev/null +++ b/src/components/InfoBox/InfoBox.tsx @@ -0,0 +1,15 @@ +import React from "react" +import styles from "./InfoBox.module.css" + +interface InfoBoxProps { + children: React.ReactNode + className?: string +} + +export const InfoBox: React.FC = ({ children, className }) => { + return ( +
{children}
+ ) +} + +export default InfoBox diff --git a/src/components/InfoBox/index.ts b/src/components/InfoBox/index.ts new file mode 100644 index 00000000..7e71df22 --- /dev/null +++ b/src/components/InfoBox/index.ts @@ -0,0 +1 @@ +export { default, InfoBox } from "./InfoBox" diff --git a/src/components/PlatformCard/PlatformCard.module.css b/src/components/PlatformCard/PlatformCard.module.css new file mode 100644 index 00000000..8b710ed5 --- /dev/null +++ b/src/components/PlatformCard/PlatformCard.module.css @@ -0,0 +1,18 @@ +.platformCard { + display: flex; + align-items: center; + background: var(--imf-list-card-background-color); + border-radius: 8px; + padding: 1.3rem; + border: 2px solid var(--ifm-background-color-secondary); +} + +.platformIcon { + width: 32px; + height: 32px; + margin-right: 16px; +} + +[data-theme="dark"] .platformIcon { + filter: invert(1); +} diff --git a/src/components/PlatformCard/PlatformCard.tsx b/src/components/PlatformCard/PlatformCard.tsx new file mode 100644 index 00000000..d94b7ff0 --- /dev/null +++ b/src/components/PlatformCard/PlatformCard.tsx @@ -0,0 +1,23 @@ +import React from "react" +import styles from "./PlatformCard.module.css" + +interface PlatformCardProps { + imageSrc: string + name: string + className?: string +} + +export const PlatformCard: React.FC = ({ + imageSrc, + name, + className, +}) => { + return ( +
+ {name} + {name} +
+ ) +} + +export default PlatformCard diff --git a/src/components/PlatformCard/index.ts b/src/components/PlatformCard/index.ts new file mode 100644 index 00000000..ca2c1258 --- /dev/null +++ b/src/components/PlatformCard/index.ts @@ -0,0 +1 @@ +export { PlatformCard, default } from "./PlatformCard" diff --git a/src/components/PlatformGrid/PlatformGrid.module.css b/src/components/PlatformGrid/PlatformGrid.module.css new file mode 100644 index 00000000..dcef77a3 --- /dev/null +++ b/src/components/PlatformGrid/PlatformGrid.module.css @@ -0,0 +1,6 @@ +.platformGrid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + margin: 1.5rem 0; +} diff --git a/src/components/PlatformGrid/PlatformGrid.tsx b/src/components/PlatformGrid/PlatformGrid.tsx new file mode 100644 index 00000000..706d006a --- /dev/null +++ b/src/components/PlatformGrid/PlatformGrid.tsx @@ -0,0 +1,20 @@ +import React from "react" +import styles from "./PlatformGrid.module.css" + +interface PlatformGridProps { + children: React.ReactNode + className?: string +} + +export const PlatformGrid: React.FC = ({ + children, + className, +}) => { + return ( +
+ {children} +
+ ) +} + +export default PlatformGrid diff --git a/src/components/PlatformGrid/index.ts b/src/components/PlatformGrid/index.ts new file mode 100644 index 00000000..843327a1 --- /dev/null +++ b/src/components/PlatformGrid/index.ts @@ -0,0 +1 @@ +export { PlatformGrid, default } from "./PlatformGrid" diff --git a/src/css/custom.css b/src/css/custom.css index 933d51d0..08ed5cb8 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -39,6 +39,12 @@ --ifm-navbar-height: 5rem; --ifm-font-family-base: "Poppins", "Work Sans", sans-serif; --ifm-background-color-primary: #f6f6f1; + --ifm-background-color-secondary: #e8e8e8; + --ifm-breadcrumb-item-background-active: #ffe9e2; + --imf-list-card-background-color: #ffffff; + --imf-list-bullets-color: #25bab1; + --imf-color-background-orange-light: #fffcfb; + --imf-color-border-orange: #ffceb6; } [data-theme="dark"] { @@ -51,6 +57,12 @@ --ifm-color-primary-lightest: #171717; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); --ifm-background-color-primary: #171717; + --ifm-background-color-secondary: #232323; + --ifm-breadcrumb-item-background-active: #3f322e; + --imf-list-card-background-color: #232323; + --imf-list-bullets-color: #208682; + --imf-color-background-orange-light: #232323; + --imf-color-border-orange: #232323; } #__docusaurus { diff --git a/static/img/overview/Azure.png b/static/img/overview/Azure.png new file mode 100644 index 0000000000000000000000000000000000000000..6e8b02eef1b3fef67e8137af5a4a1adf6288ef2c GIT binary patch literal 1864 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 CCTuAH literal 0 HcmV?d00001 diff --git a/static/img/overview/Bitbucket.png b/static/img/overview/Bitbucket.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3499137121aa183b60d00f6a2d4e2ec599ef96 GIT binary patch literal 1468 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 Date: Wed, 9 Jul 2025 16:25:11 +0530 Subject: [PATCH 2/7] docs: add Quickstart guide and replace FeatureList with ListItems component --- .../{quickstart.md => quickstart.mdx} | 50 +++++++++++++++---- docs/overview/introduction.mdx | 8 +-- src/components/FeatureList/FeatureList.tsx | 24 --------- src/components/FeatureList/index.ts | 1 - .../ListItems.module.css} | 31 ++++++++++++ src/components/ListItems/ListItems.tsx | 31 ++++++++++++ src/components/ListItems/index.ts | 1 + src/components/Note/Note.module.css | 42 ++++++++++++++++ src/components/Note/Note.tsx | 18 +++++++ src/components/Note/index.ts | 1 + src/css/custom.css | 5 ++ 11 files changed, 172 insertions(+), 40 deletions(-) rename docs/getting-started/{quickstart.md => quickstart.mdx} (85%) delete mode 100644 src/components/FeatureList/FeatureList.tsx delete mode 100644 src/components/FeatureList/index.ts rename src/components/{FeatureList/FeatureList.module.css => ListItems/ListItems.module.css} (62%) create mode 100644 src/components/ListItems/ListItems.tsx create mode 100644 src/components/ListItems/index.ts create mode 100644 src/components/Note/Note.module.css create mode 100644 src/components/Note/Note.tsx create mode 100644 src/components/Note/index.ts diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.mdx similarity index 85% rename from docs/getting-started/quickstart.md rename to docs/getting-started/quickstart.mdx index c6f1d3b8..ac7104e0 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.mdx @@ -5,22 +5,35 @@ description: See CodeRabbit in action, using a live GitHub repository. sidebar_position: 1 --- +import ListItems from "../../src/components/ListItems" +import InfoBox from "../../src/components/InfoBox" +import Note from "../../src/components/Note" + # Quickstart This tutorial gives you a hands-on demonstration of CodeRabbit, using a real, GitHub-based repository. It guides you through the following tasks: -1. Integrate CodeRabbit into a GitHub-based repository that you own. -1. Observe CodeRabbit perform a code review of a pull request that you initiate. -1. Converse with CodeRabbit about the code review. -1. Prompt CodeRabbit to generate its own improvements to the pull request. + When you complete this tutorial, you'll have seen CodeRabbit's code-review feature in action, and glimpsed a few of its other AI-driven abilities as well. -For a more general overview of CodeRabbit, see [Introduction](/). + + For a more general overview of CodeRabbit, see Introduction. + -:::note -While this tutorial focuses on GitHub, CodeRabbit also works with GitLab, Azure DevOps, and Bitbucket. For more information, see [Integrate with Git platforms](/platforms/). -::: + + While this tutorial focuses on GitHub, CodeRabbit also works with GitLab, + Azure DevOps, and Bitbucket. For more information, see{" "} + Integrate with Git platforms. + ## Before you begin @@ -30,9 +43,24 @@ Create a new, private repository on GitHub. Name the new repository `coderabbit- To integrate CodeRabbit with your GitHub account, follow these steps: -1. Visit [the CodeRabbit login page](https://app.coderabbit.ai/login?free-trial). -1. Click **Login with GitHub**. -1. Click **Authorize coderabbitai**. + + Visit{" "} + + the CodeRabbit login page + + . + , + <> + Click Login with GitHub. + , + <> + Click Authorize coderabbitai. + , + ]} +/> CodeRabbit takes a moment to set up the integration. After it finishes, the CodeRabbit dashboard appears. diff --git a/docs/overview/introduction.mdx b/docs/overview/introduction.mdx index 0af6c14f..45c6b796 100644 --- a/docs/overview/introduction.mdx +++ b/docs/overview/introduction.mdx @@ -9,7 +9,7 @@ description: slug: "/" --- -import FeatureList from "../../src/components/FeatureList" +import ListItems from "../../src/components/ListItems" import InfoBox from "../../src/components/InfoBox" import PlatformGrid from "../../src/components/PlatformGrid" import PlatformCard from "../../src/components/PlatformCard" @@ -37,7 +37,7 @@ Developers can interact directly with the CodeRabbit bot within their existing G Core CodeRabbit features include the following: - Quickstart lets you experience diff --git a/src/components/FeatureList/FeatureList.tsx b/src/components/FeatureList/FeatureList.tsx deleted file mode 100644 index 2a674bdf..00000000 --- a/src/components/FeatureList/FeatureList.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react" -import styles from "./FeatureList.module.css" - -interface FeatureListProps { - items: React.ReactNode[] - className?: string -} - -export const FeatureList: React.FC = ({ - items, - className, -}) => { - return ( -
-
    - {items.map((item, index) => ( -
  • {item}
  • - ))} -
-
- ) -} - -export default FeatureList diff --git a/src/components/FeatureList/index.ts b/src/components/FeatureList/index.ts deleted file mode 100644 index 3c506661..00000000 --- a/src/components/FeatureList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { FeatureList, default } from "./FeatureList" diff --git a/src/components/FeatureList/FeatureList.module.css b/src/components/ListItems/ListItems.module.css similarity index 62% rename from src/components/FeatureList/FeatureList.module.css rename to src/components/ListItems/ListItems.module.css index b1beca83..e671f8cb 100644 --- a/src/components/FeatureList/FeatureList.module.css +++ b/src/components/ListItems/ListItems.module.css @@ -12,6 +12,12 @@ padding: 0; } +.crOrderedList { + list-style: decimal; + margin: 0; + padding-left: 1.5em; +} + .crFeatureList li { position: relative; padding-left: 1.7em; @@ -20,6 +26,21 @@ line-height: 1.6; } +.crFeatureList li:last-child { + margin-bottom: 0; +} + +.crOrderedList li { + margin-bottom: 1em; + font-size: 1.08rem; + line-height: 1.6; + padding-left: 0.3em; +} + +.crOrderedList li:last-child { + margin-bottom: 0; +} + .crFeatureList li:before { content: ""; position: absolute; @@ -38,6 +59,16 @@ font-weight: 500; } +.crOrderedList li a { + color: var(--ifm-color-primary, orange); + text-decoration: none; + font-weight: 500; +} + .crFeatureList li a:hover { text-decoration: underline; } + +.crOrderedList li a:hover { + text-decoration: underline; +} diff --git a/src/components/ListItems/ListItems.tsx b/src/components/ListItems/ListItems.tsx new file mode 100644 index 00000000..6f87105f --- /dev/null +++ b/src/components/ListItems/ListItems.tsx @@ -0,0 +1,31 @@ +import React from "react" +import styles from "./ListItems.module.css" + +interface ListItemsProps { + items: React.ReactNode[] + className?: string + orderedList?: boolean +} + +export const ListItems: React.FC = ({ + items, + className, + orderedList = false, +}) => { + const ListTag = orderedList ? "ol" : "ul" + const listClassName = orderedList + ? styles.crOrderedList + : styles.crFeatureList + + return ( +
+ + {items.map((item, index) => ( +
  • {item}
  • + ))} +
    +
    + ) +} + +export default ListItems diff --git a/src/components/ListItems/index.ts b/src/components/ListItems/index.ts new file mode 100644 index 00000000..e4d4326c --- /dev/null +++ b/src/components/ListItems/index.ts @@ -0,0 +1 @@ +export { default, ListItems } from "./ListItems" diff --git a/src/components/Note/Note.module.css b/src/components/Note/Note.module.css new file mode 100644 index 00000000..f1494084 --- /dev/null +++ b/src/components/Note/Note.module.css @@ -0,0 +1,42 @@ +.note { + display: flex; + flex-direction: column; + align-items: flex-start; + background: var(--imf-note-background-color); + border: 2px solid var(--imf-note-border-color); + border-radius: 8px; + padding: 1rem 1.2rem; + margin: 1.2rem 0; + font-size: 1rem; +} + +.header { + display: flex; + align-items: center; + margin-bottom: 0.3em; +} + +.icon { + font-size: 1.3em; + margin-right: 0.5em; + color: #2ec4b6; + flex-shrink: 0; +} + +.title { + font-weight: 600; + color: var(--imf-note-text-color); +} + +.text { + margin-top: 0.2em; +} +.note.text p { + margin: 0px; +} +.note a { + color: var(--imf-note-text-color); +} +.note p { + margin: 0rem; +} diff --git a/src/components/Note/Note.tsx b/src/components/Note/Note.tsx new file mode 100644 index 00000000..4b85ad6c --- /dev/null +++ b/src/components/Note/Note.tsx @@ -0,0 +1,18 @@ +import React from "react" +import styles from "./Note.module.css" + +interface NoteProps { + children: React.ReactNode +} + +const Note: React.FC = ({ children }) => ( +
    +
    + ℹ️ + Note +
    +
    {children}
    +
    +) + +export default Note diff --git a/src/components/Note/index.ts b/src/components/Note/index.ts new file mode 100644 index 00000000..dd6db3eb --- /dev/null +++ b/src/components/Note/index.ts @@ -0,0 +1 @@ +export { default } from "./Note" diff --git a/src/css/custom.css b/src/css/custom.css index 08ed5cb8..cec3a337 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -45,6 +45,9 @@ --imf-list-bullets-color: #25bab1; --imf-color-background-orange-light: #fffcfb; --imf-color-border-orange: #ffceb6; + --imf-note-border-color: #25bab1; + --imf-note-background-color: #f1fffe; + --imf-note-text-color: #208682; } [data-theme="dark"] { @@ -63,6 +66,8 @@ --imf-list-bullets-color: #208682; --imf-color-background-orange-light: #232323; --imf-color-border-orange: #232323; + --imf-note-border-color: #208682; + --imf-note-background-color: #252828; } #__docusaurus { From 24e6ad7f31f9d02249aa6800557e8b1f84e7d214 Mon Sep 17 00:00:00 2001 From: Mohammed Khan Date: Fri, 11 Jul 2025 02:15:28 +0530 Subject: [PATCH 3/7] docs: WIP Quickstart ##438 --- docs/getting-started/quickstart.mdx | 65 +++++++++++-------- docusaurus.config.ts | 4 +- .../ChatBubble/ChatBubble.module.css | 11 ++++ src/components/ChatBubble/ChatBubble.tsx | 10 +++ src/components/ChatBubble/index.ts | 1 + src/components/OrderedSteps.tsx | 11 ++++ src/css/custom.css | 17 +++++ 7 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 src/components/ChatBubble/ChatBubble.module.css create mode 100644 src/components/ChatBubble/ChatBubble.tsx create mode 100644 src/components/ChatBubble/index.ts create mode 100644 src/components/OrderedSteps.tsx diff --git a/docs/getting-started/quickstart.mdx b/docs/getting-started/quickstart.mdx index ac7104e0..36dad776 100644 --- a/docs/getting-started/quickstart.mdx +++ b/docs/getting-started/quickstart.mdx @@ -8,6 +8,8 @@ sidebar_position: 1 import ListItems from "../../src/components/ListItems" import InfoBox from "../../src/components/InfoBox" import Note from "../../src/components/Note" +import CodeBlock from "@theme/CodeBlock" +import ChatBubble from "../../src/components/ChatBubble" # Quickstart @@ -85,33 +87,42 @@ The following steps initiate a pull request to add a tiny and somewhat flawed Py Use your usual Git workflow to perform the following steps in the `coderabbit-test` repository: -1. Create a branch named `add-utils`. - -1. In that new `add-utils` branch, create a new file called `simple_utils.py`, with the following content: - - ```python - # simple_utils.py - A tiny utility library + + In that new add-utils branch, create a new file called simple_utils.py, with the following content: + {` +# simple_utils.py - A tiny utility library - def reverse_string(text): - """Reverses the characters in a string.""" - return text[::-1] +def reverse_string(text): +"""Reverses the characters in a string.""" +return text[::-1] - def count_words(sentence): - return len(sentence.split()) +def count_words(sentence): +return len(sentence.split()) - def celsius_to_fahrenheit(celsius): - return (celsius * 9/5) + 32 - ``` +def celsius_to_fahrenheit(celsius): +return (celsius \* 9/5) + 32 +`} + , + "Commit the added file to the `add-utils`branch. Use any text you want for the commit message.", + "Create a pull request that proposes to merge the`add-utils`branch into the`main` branch. Use any text you want for the pull request message.", +]} +/> -1. Commit the added file to the `add-utils` branch. Use any text you want for the commit message. +After a few moments, CodeRabbit responds to the pull request using the `@coderabbitai` GitHub account. It performs the following actions, all of which are visible on the pull request's page on GitHub: -1. Create a pull request that proposes to merge the `add-utils` branch into the `main` branch. Use any text you want for the pull request message. + Part of the review resembles the following screenshot: @@ -131,13 +142,15 @@ After CodeRabbit reviews a pull request, you can converse with it about its revi After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: - > You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. - > - > While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. - > - > If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository? + + {`> You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. +> +> While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. +> +> If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository?`} + - In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. +In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. 1. Post the following as another new comment: diff --git a/docusaurus.config.ts b/docusaurus.config.ts index f4cd07ca..721da114 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -273,8 +273,8 @@ const config: Config = { ], }, prism: { - theme: prismThemes.github, - darkTheme: prismThemes.dracula, + theme: prismThemes.nightOwl, + darkTheme: prismThemes.nightOwl, }, algolia: { // The application ID provided by Algolia diff --git a/src/components/ChatBubble/ChatBubble.module.css b/src/components/ChatBubble/ChatBubble.module.css new file mode 100644 index 00000000..862055ba --- /dev/null +++ b/src/components/ChatBubble/ChatBubble.module.css @@ -0,0 +1,11 @@ +.chatBubble { + background: var(--imf-text-button-color-bg); + color: #222; + border-radius: 6px; + padding: 1em 1.2em; + margin: 1em 0; + font-family: "Fira Mono", "Menlo", "Monaco", "Consolas", monospace; + font-size: 0.98em; + white-space: pre-wrap; + word-break: break-word; +} diff --git a/src/components/ChatBubble/ChatBubble.tsx b/src/components/ChatBubble/ChatBubble.tsx new file mode 100644 index 00000000..02850637 --- /dev/null +++ b/src/components/ChatBubble/ChatBubble.tsx @@ -0,0 +1,10 @@ +import React from "react" +import styles from "./ChatBubble.module.css" + +export default function ChatBubble({ + children, +}: { + children: React.ReactNode +}) { + return
    {children}
    +} diff --git a/src/components/ChatBubble/index.ts b/src/components/ChatBubble/index.ts new file mode 100644 index 00000000..919031d1 --- /dev/null +++ b/src/components/ChatBubble/index.ts @@ -0,0 +1 @@ +export { default } from "./ChatBubble" diff --git a/src/components/OrderedSteps.tsx b/src/components/OrderedSteps.tsx new file mode 100644 index 00000000..505ed5c8 --- /dev/null +++ b/src/components/OrderedSteps.tsx @@ -0,0 +1,11 @@ +import React from "react" + +export default function OrderedSteps({ children }) { + return ( +
      + {React.Children.map(children, (child, idx) => ( +
    1. {child}
    2. + ))} +
    + ) +} diff --git a/src/css/custom.css b/src/css/custom.css index cec3a337..0bce597c 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -48,6 +48,9 @@ --imf-note-border-color: #25bab1; --imf-note-background-color: #f1fffe; --imf-note-text-color: #208682; + --imf-text-color-bg: #e8e8e8; + --imf-text-color: #171717; + --imf-text-button-color-bg: #e8e8e8; } [data-theme="dark"] { @@ -68,6 +71,9 @@ --imf-color-border-orange: #232323; --imf-note-border-color: #208682; --imf-note-background-color: #252828; + --imf-text-color-bg: #232323; + --imf-text-color: #f5f5f5; + --imf-text-button-color-bg: #e8e8e8; } #__docusaurus { @@ -315,3 +321,14 @@ a[docid="docs"] > svg { .pagination-nav { display: none; } +.language-text { + background-color: var(--imf-text-color-bg) !important; +} +.language-text .token-line { + color: var(--imf-text-color) !important; +} +.language-text [class*="buttonGroup"] button { + background-color: var(--imf-text-color-bg) !important; + color: var(--imf-text-color) !important; + border-radius: 4px; +} From 2991900608d20b30a467038fa8f792383dbf15ca Mon Sep 17 00:00:00 2001 From: Prasad Bhat Date: Wed, 16 Jul 2025 11:35:12 +0530 Subject: [PATCH 4/7] docs: added quickstart page (#438) --- docs/getting-started/quickstart.mdx | 97 +++++----- .../DarkCodeBlock/DarkCodeBlock.module.css | 131 +++++++++++++ .../DarkCodeBlock/DarkCodeBlock.tsx | 182 ++++++++++++++++++ src/components/DarkCodeBlock/index.ts | 1 + src/components/Note/Note.module.css | 4 +- src/components/Note/Note.tsx | 2 +- src/css/custom.css | 58 +++--- ...t 2025-07-16 at 8.10.33\342\200\257AM.png" | Bin 0 -> 97998 bytes static/img/Icons/Icons.png | Bin 0 -> 1686 bytes 9 files changed, 397 insertions(+), 78 deletions(-) create mode 100644 src/components/DarkCodeBlock/DarkCodeBlock.module.css create mode 100644 src/components/DarkCodeBlock/DarkCodeBlock.tsx create mode 100644 src/components/DarkCodeBlock/index.ts create mode 100644 "static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" create mode 100644 static/img/Icons/Icons.png diff --git a/docs/getting-started/quickstart.mdx b/docs/getting-started/quickstart.mdx index 36dad776..8f6190db 100644 --- a/docs/getting-started/quickstart.mdx +++ b/docs/getting-started/quickstart.mdx @@ -5,11 +5,12 @@ description: See CodeRabbit in action, using a live GitHub repository. sidebar_position: 1 --- -import ListItems from "../../src/components/ListItems" -import InfoBox from "../../src/components/InfoBox" -import Note from "../../src/components/Note" import CodeBlock from "@theme/CodeBlock" import ChatBubble from "../../src/components/ChatBubble" +import DarkCodeBlock from "../../src/components/DarkCodeBlock" +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" # Quickstart @@ -70,14 +71,21 @@ CodeRabbit takes a moment to set up the integration. After it finishes, the Code To add CodeRabbit to your test repository, follow these steps: -1. On the CodeRabbit dashboard, click **Add Repositories**. A GitHub repository-access dialog appears. -1. Select the **Only select repositories** radio button. -1. From the **Select repositories** menu, select the `coderabbit-test` repository that you created earlier in this Quickstart. -1. Click **Install & Authorize**. - :::note - CodeRabbit requests read and write access to your repository in order for its code review, issue management, and pull request generation features to work. CodeRabbit never stores your code. For more information, see [the CodeRabbit Trust Center](https://trust.coderabbit.ai). - ::: -1. If a CodeRabbit **Complete your signup** dialog appears, then fill it out with the requested information before continuing. +On the CodeRabbit dashboard, click Add Repositories., + <>Select the Only select repositories radio button., + <>From the Select repositories menu, select the coderabbit-test repository that you created earlier in this Quickstart., + <> + Click Install & Authorize. + + CodeRabbit requests read and write access to your repository in order for its code review, issue management, and pull request generation features to work. CodeRabbit never stores your code. For more information, see the CodeRabbit Trust Center. + + , + <>If a CodeRabbit Complete your signup dialog appears, then fill it out with the requested information before continuing., + ]} +/> CodeRabbit is now ready to use with your test repository. The next steps demonstrate its core code-review features. @@ -93,19 +101,18 @@ Use your usual Git workflow to perform the following steps in the `coderabbit-te "Create a branch named `add-utils`.", <> In that new add-utils branch, create a new file called simple_utils.py, with the following content: - {` -# simple_utils.py - A tiny utility library + {`# simple_utils.py - A tiny utility library def reverse_string(text): -"""Reverses the characters in a string.""" -return text[::-1] + """Reverses the characters in a string.""" + return text[::-1] def count_words(sentence): -return len(sentence.split()) + return len(sentence.split()) def celsius_to_fahrenheit(celsius): -return (celsius \* 9/5) + 32 -`} + return (celsius * 9/5) + 32 +`} , "Commit the added file to the `add-utils`branch. Use any text you want for the commit message.", "Create a pull request that proposes to merge the`add-utils`branch into the`main` branch. Use any text you want for the pull request message.", @@ -116,12 +123,10 @@ After a few moments, CodeRabbit responds to the pull request using the `@coderab If you didn't write a pull request summary, then CodeRabbit adds a new summary to the pull request., + <>CodeRabbit posts a comment titled Walkthrough containing analysis and commentary about the content of the pull request., + <>CodeRabbit attaches a detailed code review to the pull request as another comment., + ]} /> Part of the review resembles the following screenshot: @@ -136,33 +141,31 @@ After CodeRabbit reviews a pull request, you can converse with it about its revi 1. Post the following as a new GitHub comment attached to the pull request: - ```text - @coderabbitai Why do all of these functions need docstrings? Isn't it obvious enough what they do? - ``` +@coderabbitai Why do all of these functions need docstrings? Isn't it obvious enough what they do? - After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: +After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: - {`> You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. -> -> While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. -> -> If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository?`} +{`You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. + + While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. + + If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository?`} In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. -1. Post the following as another new comment: +2. Post the following as another new comment: - ```text - @coderabbitai generate docstrings - ``` +@coderabbitai generate docstrings - After a few moments, CodeRabbit does the following: +After a few moments, CodeRabbit does the following: - - CodeRabbit creates a new branch, based on `add-utils`. - - CodeRabbit commits changes to the branch that adds suggested docstrings to `add-utils`. - - CodeRabbit opens a new pull request between the new branch and `add-utils`. +CodeRabbit creates a new branch, based on `add-utils`., + <>CodeRabbit commits changes to the branch that adds suggested docstrings to `add-utils`., + <>CodeRabbit opens a new pull request between the new branch and `add-utils`., +]} /> ## Clean up @@ -172,8 +175,10 @@ You are now ready to add CodeRabbit to other repositories that you own, and let ## What's next -- [Integrate CodeRabbit](/platforms/) with your repositories on GitHub, GitLab, Azure DevOps, or Bitbucket. -- [Configure CodeRabbit](/getting-started/configure-coderabbit) beyond its default settings. -- [Add custom review instructions](/guides/review-instructions). -- [Get support for CodeRabbit](/getting-started/support). -- [Learn more about how CodeRabbit works](/overview/why-coderabbit). +Integrate CodeRabbit with your repositories on GitHub, GitLab, Azure DevOps, or Bitbucket., + <>Configure CodeRabbit beyond its default settings., + <>Add custom review instructions., + <>Get support for CodeRabbit., + <>Learn more about how CodeRabbit works., +]} /> diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.module.css b/src/components/DarkCodeBlock/DarkCodeBlock.module.css new file mode 100644 index 00000000..e424a52c --- /dev/null +++ b/src/components/DarkCodeBlock/DarkCodeBlock.module.css @@ -0,0 +1,131 @@ +.codeBlock { + margin: 1rem 0; + border-radius: 8px; + overflow: hidden; + background-color: #1a1a1a; + border: none; + font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace; + position: relative; +} + +.codeHeader { + background-color: #1a1a1a; + padding: 0.75rem 1rem; + border-bottom: 1px solid #333; + color: #888; + font-size: 0.875rem; + font-weight: 400; + font-style: italic; +} + +.codeTitle { + color: #888; + font-style: italic; +} + +.codeContainer { + position: relative; + background-color: #1a1a1a; +} + +.codeContent { + margin: 0; + padding: 1rem; + padding-bottom: 2rem; + background-color: transparent; + color: #e6e6e6; + font-size: 0.875rem; + line-height: 1.6; + overflow-x: auto; + white-space: pre; +} + +.codeLine { + display: block; + min-height: 1.6rem; +} + +.copyButtonContainer { + background-color: #1a1a1a; + padding: 0.75rem 1rem; + display: flex; + justify-content: flex-end; + cursor: pointer; +} + +.copyButton { + background-color: #333; + color: #fff; + border: 1px solid #333; + border-radius: 4px; + padding: 0.5rem 0.75rem; + font-size: 0.75rem; + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; + transition: all 0.2s ease; + font-family: inherit; + width: 100%; + justify-content: flex-end; +} + +.copyButton:hover { + background-color: #333; + color: #fff; + border-color: #666; +} + +.copyButton:active { + transform: scale(0.98); +} + +.copyButton svg { + width: 14px; + height: 14px; +} + +.codeContent :global(.keyword) { + color: #4fc1ff; + font-weight: 400; +} + +.codeContent :global(.comment) { + color: #6a9955; + font-style: italic; +} + +.codeContent :global(.string) { + color: #ff6b9d; +} + +.codeContent :global(.function) { + color: #ffab70; + font-weight: 400; +} + +.codeContent :global(.number) { + color: #53FFE8; +} + +.codeContent :global(.header) { + color: #e6e6e6; + font-style: italic; +} + +@media (max-width: 768px) { + .codeContent { + font-size: 0.8rem; + padding: 0.75rem; + padding-bottom: 3rem; + } + + .copyButton { + font-size: 0.7rem; + padding: 0.4rem 0.6rem; + } + + .copyButtonContainer { + padding: 0.5rem 0.75rem; + } +} diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.tsx b/src/components/DarkCodeBlock/DarkCodeBlock.tsx new file mode 100644 index 00000000..47a4775c --- /dev/null +++ b/src/components/DarkCodeBlock/DarkCodeBlock.tsx @@ -0,0 +1,182 @@ +import React, { useState, useMemo } from 'react'; +import styles from './DarkCodeBlock.module.css'; + +interface DarkCodeBlockProps { + children: string; + language?: string; + title?: string; +} + +const DarkCodeBlock: React.FC = ({ + children, + language = 'python', + title +}) => { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(children); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy text: ', err); + } + }; + + const KEYWORDS = useMemo(() => ['def', 'return', 'if', 'else', 'elif', 'for', 'while', 'class', 'import', 'from', 'as', 'try', 'except', 'finally', 'with', 'pass', 'break', 'continue', 'and', 'or', 'not', 'in', 'is', 'lambda', 'yield', 'global', 'nonlocal', 'assert', 'del', 'raise', 'True', 'False', 'None'], []); + + const highlightedCode = useMemo(() => { + const highlightCode = (code: string, lang: string) => { + const lines = code.trim().split('\n'); + + return lines.map((line, index) => { + if (lang === 'python') { + const tokens = []; + let i = 0; + const text = line; + + while (i < text.length) { + if (/\s/.test(text[i])) { + let start = i; + while (i < text.length && /\s/.test(text[i])) i++; + tokens.push({ type: 'whitespace', value: text.substring(start, i) }); + continue; + } + + if (text[i] === '#') { + const commentText = text.substring(i); + if (index === 0 && commentText.includes('.py')) { + tokens.push({ type: 'header', value: commentText }); + } else { + tokens.push({ type: 'comment', value: commentText }); + } + break; + } + + if (text.substring(i, i + 3) === '"""' || text.substring(i, i + 3) === "'''") { + const quote = text.substring(i, i + 3); + let end = i + 3; + while (end < text.length - 2 && text.substring(end, end + 3) !== quote) { + end++; + } + if (end < text.length - 2) end += 3; + tokens.push({ type: 'string', value: text.substring(i, end) }); + i = end; + continue; + } + + if (text[i] === '"' || text[i] === "'") { + const quote = text[i]; + let end = i + 1; + while (end < text.length && text[end] !== quote) { + if (text[end] === '\\') end += 2; + else end++; + } + if (end < text.length) end++; + tokens.push({ type: 'string', value: text.substring(i, end) }); + i = end; + continue; + } + + if (/\d/.test(text[i])) { + let start = i; + while (i < text.length && /[\d.]/.test(text[i])) i++; + tokens.push({ type: 'number', value: text.substring(start, i) }); + continue; + } + + if (/[a-zA-Z_]/.test(text[i])) { + let start = i; + while (i < text.length && /[a-zA-Z0-9_]/.test(text[i])) i++; + const word = text.substring(start, i); + + if (KEYWORDS.includes(word)) { + tokens.push({ type: 'keyword', value: word }); + } else { + const prevKeywordToken = tokens.filter(t => t.type !== 'whitespace').pop(); + if (prevKeywordToken && prevKeywordToken.value === 'def') { + tokens.push({ type: 'function', value: word }); + } else { + tokens.push({ type: 'identifier', value: word }); + } + } + continue; + } + + tokens.push({ type: 'operator', value: text[i] }); + i++; + } + + const htmlParts = tokens.map(token => { + switch (token.type) { + case 'keyword': + return `${token.value}`; + case 'string': + return `${token.value}`; + case 'function': + return `${token.value}`; + case 'number': + return `${token.value}`; + case 'comment': + return `${token.value}`; + case 'header': + return `${token.value}`; + case 'whitespace': + case 'operator': + case 'identifier': + default: + return token.value; + } + }); + + return ( +
    + +
    + ); + } + + return ( +
    + {line} +
    + ); + }); + }; + + return highlightCode(children, language); + }, [children, language, KEYWORDS]); + + return ( +
    + {title && ( +
    + {title} +
    + )} +
    +
    +          
    +            {highlightedCode}
    +          
    +        
    +
    + +
    +
    +
    + ); +}; + +export default DarkCodeBlock; diff --git a/src/components/DarkCodeBlock/index.ts b/src/components/DarkCodeBlock/index.ts new file mode 100644 index 00000000..ee453e50 --- /dev/null +++ b/src/components/DarkCodeBlock/index.ts @@ -0,0 +1 @@ +export { default } from './DarkCodeBlock'; \ No newline at end of file diff --git a/src/components/Note/Note.module.css b/src/components/Note/Note.module.css index f1494084..e4f27ae6 100644 --- a/src/components/Note/Note.module.css +++ b/src/components/Note/Note.module.css @@ -17,9 +17,9 @@ } .icon { - font-size: 1.3em; + width: 1.5em; + height: 1.5em; margin-right: 0.5em; - color: #2ec4b6; flex-shrink: 0; } diff --git a/src/components/Note/Note.tsx b/src/components/Note/Note.tsx index 4b85ad6c..10ce1247 100644 --- a/src/components/Note/Note.tsx +++ b/src/components/Note/Note.tsx @@ -8,7 +8,7 @@ interface NoteProps { const Note: React.FC = ({ children }) => (
    - ℹ️ + Note Note
    {children}
    diff --git a/src/css/custom.css b/src/css/custom.css index ecb8dde9..5a0e7b98 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -92,27 +92,6 @@ a[docid="docs"] > svg { display: none; } -/* Adjustments for mobile view */ -@media (max-width: 768px) { - /* Reduce the logo size for smaller screens */ - .navbar__logo img { - height: 32px; - align-items: center; - } - - /* Reduce the padding around the logo for smaller screens */ - .navbar__logo { - padding: 2px; /* Adjust the padding for smaller screens */ - } -} - -/* Center the Discord link within its parent */ -.navbar__items.navbar__items--right { - display: flex; - justify-content: center; - align-items: center; -} - [data-theme="light"] img[src$="#gh-dark-mode-only"], [data-theme="dark"] img[src$="#gh-light-mode-only"] { display: none; @@ -148,7 +127,14 @@ a[docid="docs"] > svg { display: none; } -/* Adjustments for mobile view */ +/* Center the Discord link within its parent */ +.navbar__items.navbar__items--right { + display: flex; + justify-content: center; + align-items: center; +} + +/* Consolidated mobile view adjustments */ @media (max-width: 768px) { /* Reduce the logo size for smaller screens */ .navbar__logo img { @@ -158,15 +144,13 @@ a[docid="docs"] > svg { /* Reduce the padding around the logo for smaller screens */ .navbar__logo { - padding: 2px; /* Adjust the padding for smaller screens */ + padding: 2px; } -} -/* Center the Discord link within its parent */ -.navbar__items.navbar__items--right { - display: flex; - justify-content: center; - align-items: center; + /* Content padding for mobile */ + .markdown { + padding-left: 1rem; + } } /* Light mode Discord icon */ @@ -365,3 +349,19 @@ a[docid="docs"] > svg { cursor: default; background-color: var(--ifm-breadcrumb-item-background-active); } + +/* Add left spacing to main content */ +.markdown { + padding-left: 1.5rem; +} + +/* Align numbered lists with other content */ +.markdown ol { + padding-left: 1.2rem; + margin-left: 0; +} + +.markdown ol > li { + margin-left: 0; + padding-left: 0.5rem; +} diff --git "a/static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" "b/static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" new file mode 100644 index 0000000000000000000000000000000000000000..837d09b882ed2b7d1c37fcadd470ef40145d456c GIT binary patch literal 97998 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 G|T<<$m^-)Nqz%)olA(Pc!il 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 I$-W5tKiVx&od5s; literal 0 HcmV?d00001 diff --git a/static/img/Icons/Icons.png b/static/img/Icons/Icons.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd5b868d6984acbb0d6a98fcf80b79ff60af434 GIT binary patch literal 1686 zcmV;H25I?;P))~d6vrP($)3rkIs$V8=LA(h_OVY8`2?{yoyv(Lx^C>5ZsMH4&aS(p2WTaq!0ri( z8&uhJ#*s<%0i=>x2IvO@q@)@AHqMBQ2>%zbpeyp<39cvp@sFqCyY%X7w`CsR~OJCtq53HTl^eA3~E@KEgYY5)RvHq3z(c7 zZvzu=S`coLR)lO!z~nSd0OE7+Q`Ht0UEny5npz_p5imLV^%**bGyG@I^1n`%mu2W2 zBzg8x{fy#o(29GdciyV;y^UF;cLC8!NC%M;Z=a%td_bix0qCAoS+|H$$Q->mdkR!R z8B6)_@CZEORlwx*7o4&%c<@H)F$KJZPuaxBeh!~I0Oi>U>nu)bK76?gp716hQ9L<4 zchL$a&;Vp1J&Nc>K$3Vu;2Jbap#_rHM=8FjQRPjZM06IAu;y{-#5??_7uV1t#V#Nk zS6ZWoHPJ~xHDv^xo9{qx$~rsC3bRNeLNwq9FW*5;Y76-A;846z*>}qh`c)LP5sz^V z*)rUMJAv+#x-U6`+C){0HD3ks)Ij7Ia4hPD>cK70?K#w>mVo8d9T+a7r|o(XFZu2D zR+)ToLXCxGJ2>CC_6CfWRLEI_T2mMW{Ksg0tozt?&C@Io#Y=JhUVI^Nn_U?$V>Db&pv(5ak~&k^w7=s1_Ia8G-&0aT zjnOof8G8#2@l z79a~)WIznl$glN5xfJXdzogoJ?0XLbWimtiIeKKdcO=pQGEv`fVcJBVjUT*{`NT75 z3d{t-MkJSo`(kxvu?sFJUqhe5Lgn4=qw;y{N3mVOik^;0Rtjm*1!RU$NEimO4w%+K zfn`=ABmvc$VB9!&TFtWfC7&2BB-C|~W`UcrF%Vx?ro{(*m~t>}j~)@S+d!VeBGG=# z*cw~k9N8|SVHRxx0h$-iQ9z~(oAZy*0A(Tm{pW3yEKT0r?l+U&$^XU&+!u?1$0=+i z{ui2HGkSAp&nfbO60}Wp%}pBI1f17xeWOd2HC3P&ZXu$h1qR#%lpO=>4zuoZxC2c< z#+II%Z;r^x2#5k2)(Igj6(4W7^Xu&xMWh{~y(c8heDxYU0GJ@vD4Fkwp3O@N3+I?I^) z*|y2xt`q|FwctFz1R`_+Z*o)ORJKm^Va+I8;q)&)>P~vG@S0J;Gh0Sj$QJtYa z&@L5zlD9=esK4d_djV(StfDnyq#Agf$#xf>!DXW+I8xTOQ^Vz2%>nhgvs5dXFeNy> zbW*A3$aOW2rasz(A8ZH}u-lq|#ej~-<|OB8bf?ZKPljF@#f#Vn{_|li3wOu|X0k!Y zAP@%V8}WD*HrStAe5<-?MQ0ysQd>Y(5@b;EU@2mBwajFLnzq&b(aLeSEH_RWX+Fd? z!`!ea!9{yEUWSN;Gm9P&PdJ~Si@}lUUz17ihyG)2X|MpNalY64@q3v5IVQ)LE~u?a zp8pP&XXxbN?9m=LQrn3vlAIh}RP+zdY4i+l5evqQSBkK_YD}f>}wn;211XA@2Rfn-Z$Sq`->lz%mo>PQPEG16q=1_5UXLqfR{C|yu zHM+v_*W2d@hmCg7HZI_t7KNOuj($vfv=K_SCg7YxNSxM9{NWvtQAIPS;f;@lB~fNa zaQnfYD(7HpnJV2St7ljM!g|fJ5*JGoaFMd9vhcFGrsF~O=Sc4y$Jg-RjITb%707*qoM6N<$g3kvN6aWAK literal 0 HcmV?d00001 From d6436da6588f747b22b4b09548a07a01a9c224f5 Mon Sep 17 00:00:00 2001 From: Prasad Bhat Date: Wed, 16 Jul 2025 12:07:31 +0530 Subject: [PATCH 5/7] docs: modified chat bubble to include custom colors --- src/components/ChatBubble/ChatBubble.module.css | 2 +- src/css/custom.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ChatBubble/ChatBubble.module.css b/src/components/ChatBubble/ChatBubble.module.css index 862055ba..61f961ce 100644 --- a/src/components/ChatBubble/ChatBubble.module.css +++ b/src/components/ChatBubble/ChatBubble.module.css @@ -1,6 +1,6 @@ .chatBubble { background: var(--imf-text-button-color-bg); - color: #222; + color: var(--imf-text-color); border-radius: 6px; padding: 1em 1.2em; margin: 1em 0; diff --git a/src/css/custom.css b/src/css/custom.css index 5a0e7b98..27d4e5b3 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -73,7 +73,7 @@ --imf-note-background-color: #252828; --imf-text-color-bg: #232323; --imf-text-color: #f5f5f5; - --imf-text-button-color-bg: #e8e8e8; + --imf-text-button-color-bg: #232323; } #__docusaurus { From de79b5bdd2aa25c6ae276c33cad2b06d59520ac3 Mon Sep 17 00:00:00 2001 From: Prasad Bhat Date: Wed, 16 Jul 2025 13:31:05 +0530 Subject: [PATCH 6/7] docs: removing unnecessary screenshot (#438) --- ...hot 2025-07-16 at 8.10.33\342\200\257AM.png" | Bin 97998 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 "static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" diff --git "a/static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" "b/static/Screenshot 2025-07-16 at 8.10.33\342\200\257AM.png" deleted file mode 100644 index 837d09b882ed2b7d1c37fcadd470ef40145d456c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97998 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 G|T<<$m^-)Nqz%)olA(Pc!il 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 I$-W5tKiVx&od5s; From dd9403ce5220a3f714dfa73d51a3cd6b63be75cb Mon Sep 17 00:00:00 2001 From: Prasad Bhat Date: Fri, 18 Jul 2025 12:01:18 +0530 Subject: [PATCH 7/7] docs: add coderabbit to your repository section UI enhancements --- docs/faq.md | 6 +- docs/getting-started/adding-organizations.md | 27 --- docs/getting-started/adding-organizations.mdx | 42 ++++ docs/getting-started/quickstart.mdx | 11 +- ...rmissions.md => upgrading-permissions.mdx} | 36 ++- docs/overview/why-coderabbit.md | 2 +- docs/platforms/azure-devops.md | 102 --------- docs/platforms/azure-devops.mdx | 105 +++++++++ docs/platforms/bitbucket-cloud.md | 132 ----------- docs/platforms/bitbucket-cloud.mdx | 148 +++++++++++++ .../{github-com.md => github-com.mdx} | 44 ++-- docs/platforms/github-enterprise-server.md | 189 ---------------- docs/platforms/github-enterprise-server.mdx | 187 ++++++++++++++++ docs/platforms/gitlab-com.mdx | 130 +++++++---- docs/platforms/platforms.md | 35 --- docs/platforms/platforms.mdx | 77 +++++++ docs/platforms/self-hosted-gitlab.md | 125 ----------- docs/platforms/self-hosted-gitlab.mdx | 110 +++++++++ .../{azure-devops.md => azure-devops.mdx} | 84 ++++--- .../{bitbucket.md => bitbucket.mdx} | 78 ++++--- docs/self-hosted/{github.md => github.mdx} | 104 +++++---- docs/self-hosted/{gitlab.md => gitlab.mdx} | 114 +++++----- .../BlockQuote/BlockQuote.module.css | 33 +++ src/components/BlockQuote/BlockQuote.tsx | 14 ++ src/components/BlockQuote/index.ts | 1 + .../ChatBubble/ChatBubble.module.css | 66 ++++++ src/components/ChatBubble/ChatBubble.tsx | 39 +++- .../DarkCodeBlock/DarkCodeBlock.module.css | 15 +- .../DarkCodeBlock/DarkCodeBlock.tsx | 6 +- src/components/InfoBox/InfoBox.module.css | 17 ++ src/components/ListItems/ListItems.module.css | 96 +++++++- src/components/ListItems/ListItems.tsx | 20 +- src/components/Note/Note.module.css | 73 ++++++ src/components/Table/Table.module.css | 209 ++++++++++++++++++ src/components/Table/Table.tsx | 89 ++++++++ src/components/Table/index.ts | 2 + src/components/Tip/Tip.module.css | 84 +++++++ src/components/Tip/Tip.tsx | 20 ++ src/components/Tip/index.ts | 1 + src/components/Warning/Warning.module.css | 119 ++++++++++ src/components/Warning/Warning.tsx | 18 ++ src/components/Warning/index.ts | 1 + static/img/Icons/Tip.png | Bin 0 -> 487 bytes static/img/Icons/Vector.png | Bin 0 -> 478 bytes static/img/Icons/Warning.png | Bin 0 -> 1631 bytes 45 files changed, 1942 insertions(+), 869 deletions(-) delete mode 100644 docs/getting-started/adding-organizations.md create mode 100644 docs/getting-started/adding-organizations.mdx rename docs/getting-started/{upgrading-permissions.md => upgrading-permissions.mdx} (53%) delete mode 100644 docs/platforms/azure-devops.md create mode 100644 docs/platforms/azure-devops.mdx delete mode 100644 docs/platforms/bitbucket-cloud.md create mode 100644 docs/platforms/bitbucket-cloud.mdx rename docs/platforms/{github-com.md => github-com.mdx} (73%) delete mode 100644 docs/platforms/github-enterprise-server.md create mode 100644 docs/platforms/github-enterprise-server.mdx delete mode 100644 docs/platforms/platforms.md create mode 100644 docs/platforms/platforms.mdx delete mode 100644 docs/platforms/self-hosted-gitlab.md create mode 100644 docs/platforms/self-hosted-gitlab.mdx rename docs/self-hosted/{azure-devops.md => azure-devops.mdx} (63%) rename docs/self-hosted/{bitbucket.md => bitbucket.mdx} (64%) rename docs/self-hosted/{github.md => github.mdx} (75%) rename docs/self-hosted/{gitlab.md => gitlab.mdx} (62%) create mode 100644 src/components/BlockQuote/BlockQuote.module.css create mode 100644 src/components/BlockQuote/BlockQuote.tsx create mode 100644 src/components/BlockQuote/index.ts create mode 100644 src/components/Table/Table.module.css create mode 100644 src/components/Table/Table.tsx create mode 100644 src/components/Table/index.ts create mode 100644 src/components/Tip/Tip.module.css create mode 100644 src/components/Tip/Tip.tsx create mode 100644 src/components/Tip/index.ts create mode 100644 src/components/Warning/Warning.module.css create mode 100644 src/components/Warning/Warning.tsx create mode 100644 src/components/Warning/index.ts create mode 100644 static/img/Icons/Tip.png create mode 100644 static/img/Icons/Vector.png create mode 100644 static/img/Icons/Warning.png diff --git a/docs/faq.md b/docs/faq.md index 6755fffa..84abdd52 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -33,16 +33,16 @@ View step by step instructions depending on your platform: - See our [GitHub App installation guide](./platforms/github-com.md) for step-by-step instructions. + See our [GitHub App installation guide](./platforms/github-com.mdx) for step-by-step instructions. Follow our [GitLab integration guide](/platforms/gitlab-com.mdx) to get started. - Check out the [Bitbucket installation steps](/platforms/bitbucket-cloud.md) for detailed setup. + Check out the [Bitbucket installation steps](/platforms/bitbucket-cloud.mdx) for detailed setup. - View our [Azure DevOps setup guide](/platforms/azure-devops.md) for complete installation instructions. + View our [Azure DevOps setup guide](/platforms/azure-devops.mdx) for complete installation instructions. diff --git a/docs/getting-started/adding-organizations.md b/docs/getting-started/adding-organizations.md deleted file mode 100644 index 66741daa..00000000 --- a/docs/getting-started/adding-organizations.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Add organizations -description: Learn how to add new organizations to CodeRabbit ---- - -To add new organizations to CodeRabbit, follow these steps: - -1. Navigate to [coderabbit.ai](https://coderabbit.ai) -2. Click the "Refresh" button next to your organizations list to check for new organizations -3. Find the organization you want to add in the list -4. Click the "Grant" button next to the organization name - -![Checking for new organizations](../../static/img/getting-started/check-for-new-orgs.png) - -![Granting permission to organization](../../static/img/getting-started/grant-permission.png) - -This will grant CodeRabbit access to the selected organization, allowing it to: - -- Read organization and team membership -- Read organization projects -- Access user email addresses (read-only) - -> Note: Organizations control which applications are allowed to access their private data. You may need organization admin approval to complete this process. - -## What's next {#whats-next} - -- [Manage your subscription](/getting-started/subscription-management) diff --git a/docs/getting-started/adding-organizations.mdx b/docs/getting-started/adding-organizations.mdx new file mode 100644 index 00000000..334c1a4e --- /dev/null +++ b/docs/getting-started/adding-organizations.mdx @@ -0,0 +1,42 @@ +--- +title: Add organizations +description: Learn how to add new organizations to CodeRabbit +--- + +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" + +To add new organizations to CodeRabbit, follow these steps: + +Navigate to coderabbit.ai, + <>Click the "Refresh" button next to your organizations list to check for new organizations, + <>Find the organization you want to add in the list, + <>Click the "Grant" button next to the organization name + ]} +/> + +![Checking for new organizations](../../static/img/getting-started/check-for-new-orgs.png) + +![Granting permission to organization](../../static/img/getting-started/grant-permission.png) + +This will grant CodeRabbit access to the selected organization, allowing it to: + + + + +Organizations control which applications are allowed to access their private data. You may need organization admin approval to complete this process. + + +## What's next {#whats-next} + +- [Manage your subscription](/getting-started/subscription-management) \ No newline at end of file diff --git a/docs/getting-started/quickstart.mdx b/docs/getting-started/quickstart.mdx index 8f6190db..043efdb5 100644 --- a/docs/getting-started/quickstart.mdx +++ b/docs/getting-started/quickstart.mdx @@ -11,6 +11,7 @@ import DarkCodeBlock from "../../src/components/DarkCodeBlock" import InfoBox from "../../src/components/InfoBox" import ListItems from "../../src/components/ListItems" import Note from "../../src/components/Note" +import BlockQuote from "../../src/components/BlockQuote" # Quickstart @@ -145,13 +146,13 @@ After CodeRabbit reviews a pull request, you can converse with it about its revi After a few moments, CodeRabbit posts its reply, explaining its motivations for its recommendation. The reply might resemble the following: - -{`You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. +
    +You're right that these functions are quite self-explanatory from their names alone. Docstrings aren't strictly necessary for every function, especially in smaller projects with clear function names. - While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. +While docstrings do provide benefits (IDE tooltips, documentation generation, help for future developers), they can sometimes feel redundant for very straightforward functions. It's ultimately a matter of coding style and project requirements. - If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository?`} - +If you prefer to skip docstrings for obvious utility functions in this project, that's perfectly reasonable. Would you like me to adjust my review approach regarding documentation for this repository? +
    In this case, CodeRabbit is offering to adjust its future behavior when reviewing changes to this repository. Instead, follow the next step to ask CodeRabbit to implement part of its suggestions. diff --git a/docs/getting-started/upgrading-permissions.md b/docs/getting-started/upgrading-permissions.mdx similarity index 53% rename from docs/getting-started/upgrading-permissions.md rename to docs/getting-started/upgrading-permissions.mdx index c5553abe..768dab88 100644 --- a/docs/getting-started/upgrading-permissions.md +++ b/docs/getting-started/upgrading-permissions.mdx @@ -3,13 +3,21 @@ title: Set permissions description: Learn how to upgrade CodeRabbit's GitHub App permissions when new features are added --- +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" + Sometimes when we add new features to CodeRabbit, we need to request additional GitHub permissions. If you see a warning about permissions or resources not being accessible, you'll need to approve the new permissions. Here's how to do it: -1. Navigate to your organization or repository settings in GitHub -2. Go to the "GitHub Apps" or "Installed GitHub Apps" section -3. Find CodeRabbit in the list of installed apps -4. Click "Configure" -5. Review and accept the new permissions +Navigate to your organization or repository settings in GitHub, + <>Go to the "GitHub Apps" or "Installed GitHub Apps" section, + <>Find CodeRabbit in the list of installed apps, + <>Click "Configure", + <>Review and accept the new permissions + ]} +/> ![Permission warning example](../../static/img/getting-started/permission-warning.png) @@ -19,11 +27,17 @@ Sometimes when we add new features to CodeRabbit, we need to request additional Common reasons for permission updates include: -- Access to new GitHub features -- Enhanced repository scanning capabilities -- Additional workflow automation features -- Improved security features + -> Note: If you're not an organization admin, you may need to request approval from your organization administrators to update the permissions. + +If you're not an organization admin, you may need to request approval from your organization administrators to update the permissions. + -After accepting the new permissions, CodeRabbit will have the access it needs to function properly. If you continue to experience issues, try refreshing your browser or reaching out to our support team. +After accepting the new permissions, CodeRabbit will have the access it needs to function properly. If you continue to experience issues, try refreshing your browser or reaching out to our support team. \ No newline at end of file diff --git a/docs/overview/why-coderabbit.md b/docs/overview/why-coderabbit.md index f04e347d..e3ce5c9b 100644 --- a/docs/overview/why-coderabbit.md +++ b/docs/overview/why-coderabbit.md @@ -348,7 +348,7 @@ CodeRabbit is built for production environments with: ### Three Steps to Better Code Reviews -1. **Sign in** with [GitHub](../platforms/github-com.md), [GitLab](../platforms/gitlab-com.mdx), or [Azure DevOps](../platforms/azure-devops.md) +1. **Sign in** with [GitHub](../platforms/github-com.mdx), [GitLab](../platforms/gitlab-com.mdx), or [Azure DevOps](../platforms/azure-devops.mdx) 2. Select and add repositories in CodeRabbit dashboard 3. That's it. You're good to go. diff --git a/docs/platforms/azure-devops.md b/docs/platforms/azure-devops.md deleted file mode 100644 index 12b70765..00000000 --- a/docs/platforms/azure-devops.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Integrating CodeRabbit with Azure DevOps -description: Learn how to integrate CodeRabbit with Azure DevOps. -sidebar_label: Azure DevOps -sidebar_position: 5 ---- - -This guide will assist you in effectively integrating CodeRabbit with Azure -DevOps. - -## Prerequisites - -- An active Azure DevOps account. -- Use of organizational email addresses is required; personal email addresses - are not supported for this integration. - -## Integration Instructions - -1. Log in to the CodeRabbitAI application. -2. After logging in, you will be redirected to a page displaying Microsoft Apps - consent requests. Please forward these requests to your administrator for - approval. - - :::warning - - If you are an administrator, you may approve the applications directly. If not, - please contact your administrator to request approval for the applications. - - ::: - - ![CodeRabbit admin consent page for Azure DevOps integration](/img/integrations/azure_apps_consent_page.png) - -3. Once your administrator has approved the applications, click "Continue." -4. You will be redirected to the "Onboarding" page, where you can select the - organization you wish to integrate with. -5. On the "Azure DevOps User" page, enter your Personal Access Token for Azure - DevOps. - ![CodeRabbit azure devOps integration settings page](/img/integrations/azure_devops_user_page.png) -6. To install CodeRabbit on a repository, toggle the switch on the - "Repositories" page. - -## How it works - -For the CodeRabbit app to post reviews on merge requests, it needs to interact -with the Azure DevOps API, which requires a Personal Access Token. This token -can be generated by creating a Personal Access Token from one of your existing -users. - -You can create a new user in Azure DevOps and generate a Personal Access Token -for that user, following [our recommendations](#recommendations). - -## Azure DevOps Personal Access Tokens - -To interact with the Azure DevOps API, a **Personal Access Token** is required. -This token can be generated by creating a **Personal Access Token** from one of -your existing users. - -Upon first login to the application (immediately after the onboarding screen), -you will need to add the Personal Access Token. - -![CodeRabbit azure devOps integration modal](/img/integrations/azure_personal_access_token_add.png) - -### Recommendations - -- **Create a dedicated user for CodeRabbit** - This ensures the user is - exclusively for CodeRabbit, allowing better access control. -- **Use "CodeRabbit" as the username** - This makes the user easily recognizable - for future reference. -- **Use a dedicated email address** - This helps in easy identification and - management. -- **Use the CodeRabbit logo as the profile picture** - This further ensures easy - recognition. You can download our logo from - [here](/img/integrations/logo.png "download"). - -### Key Points to Remember - -- Personal access tokens have expiration dates. Ensure the expiration date - covers the duration of your intended use of the CodeRabbit app. -- Code reviews will be attributed to the owner of the personal access token. -- If the personal access token expires, you can add a new one via the CodeRabbit - UI: - - Navigate to the "AzureDevOps User" page in the sidebar. - - Add the new token and click save. - -### Generating a Personal Access Token - -Azure DevOps provides an option to generate a personal access token for a user. -Follow these steps to generate the token: - -1. Log in as the user intended for CodeRabbit reviews. -2. Next to your avatar on the headers right side is a settings icon, click it. -3. Choose "Personal Access Tokens" -4. Click "New Token" -5. Select the organization you want to use the token with or select "All - accessible organizations." -6. Enter a name and an expiry date for the token. -7. We need to have read & write access to "Work Items" & "Code" to post reviews - on pull requests. If you are on the Pro tier also add "Build" access for pipeline - failure remediation. -8. Click "Create" - -![CodeRabbit azure devOps personal access token creation form](/img/integrations/azure-access-token.png) diff --git a/docs/platforms/azure-devops.mdx b/docs/platforms/azure-devops.mdx new file mode 100644 index 00000000..baf2fc20 --- /dev/null +++ b/docs/platforms/azure-devops.mdx @@ -0,0 +1,105 @@ +--- +title: Integrating CodeRabbit with Azure DevOps +description: Learn how to integrate CodeRabbit with Azure DevOps. +sidebar_label: Azure DevOps +sidebar_position: 5 +--- + +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import { Warning } from "../../src/components/Warning" + +This guide will assist you in effectively integrating CodeRabbit with Azure DevOps. + +## Prerequisites + + + +## Integration Instructions + +Log in to the CodeRabbitAI application, + <>After logging in, you will be redirected to a page displaying Microsoft Apps consent requests. Please forward these requests to your administrator for approval. + + + If you are an administrator, you may approve the applications directly. If not, please contact your administrator to request approval for the applications. + + + CodeRabbit admin consent page for Azure DevOps integration, + <>Once your administrator has approved the applications, click "Continue", + <>You will be redirected to the "Onboarding" page, where you can select the organization you wish to integrate with, + <>On the "Azure DevOps User" page, enter your Personal Access Token for Azure DevOps. + + CodeRabbit azure devOps integration settings page, + <>To install CodeRabbit on a repository, toggle the switch on the "Repositories" page + ]} +/> + +## How it works + +For the CodeRabbit app to post reviews on merge requests, it needs to interact with the Azure DevOps API, which requires a Personal Access Token. This token can be generated by creating a Personal Access Token from one of your existing users. + +You can create a new user in Azure DevOps and generate a Personal Access Token for that user, following [our recommendations](#recommendations). + +## Azure DevOps Personal Access Tokens + +To interact with the Azure DevOps API, a **Personal Access Token** is required. This token can be generated by creating a **Personal Access Token** from one of your existing users. + +Upon first login to the application (immediately after the onboarding screen), you will need to add the Personal Access Token. + +![CodeRabbit azure devOps integration modal](/img/integrations/azure_personal_access_token_add.png) + +### Recommendations + +Create a dedicated user for CodeRabbit - This ensures the user is exclusively for CodeRabbit, allowing better access control, + <>Use "CodeRabbit" as the username - This makes the user easily recognizable for future reference, + <>Use a dedicated email address - This helps in easy identification and management, + <>Use the CodeRabbit logo as the profile picture - This further ensures easy recognition. You can download our logo from here + ]} +/> + +### Key Points to Remember + +Personal access tokens have expiration dates. Ensure the expiration date covers the duration of your intended use of the CodeRabbit app, + <>Code reviews will be attributed to the owner of the personal access token, + <>If the personal access token expires, you can add a new one via the CodeRabbit UI: + Navigate to the "AzureDevOps User" page in the sidebar, + <>Add the new token and click save + ]} + /> + ]} +/> + +### Generating a Personal Access Token + +Azure DevOps provides an option to generate a personal access token for a user. Follow these steps to generate the token: + +Log in as the user intended for CodeRabbit reviews, + <>Next to your avatar on the headers right side is a settings icon, click it, + <>Choose "Personal Access Tokens", + <>Click "New Token", + <>Select the organization you want to use the token with or select "All accessible organizations", + <>Enter a name and an expiry date for the token, + <>We need to have read & write access to "Work Items" & "Code" to post reviews on pull requests. If you are on the Pro tier also add "Build" access for pipeline failure remediation, + <>Click "Create" + ]} +/> + +![CodeRabbit azure devOps personal access token creation form](/img/integrations/azure-access-token.png) \ No newline at end of file diff --git a/docs/platforms/bitbucket-cloud.md b/docs/platforms/bitbucket-cloud.md deleted file mode 100644 index 385d46ed..00000000 --- a/docs/platforms/bitbucket-cloud.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: "Bitbucket Cloud" -description: "Learn how to integrate CodeRabbit with Bitbucket Cloud." -sidebar_label: "Bitbucket Cloud" -sidebar_position: 6 ---- - -CodeRabbit integrates with Bitbucket Cloud to enhance code review and collaboration by: - -- Automatically initiating code reviews for newly created merge requests. -- Displaying review comments and suggestions directly on merge requests. -- Enabling seamless interaction with the CodeRabbit bot for real-time feedback and assistance. - -This guide will assist you in effectively integrating CodeRabbit with Bitbucket Cloud. - -## Configure API Token - -To enable CodeRabbit to interact with your Bitbucket repositories, an API token is required. This token grants the -necessary permissions for interacting with the Bitbucket merge request and discussion APIs. - -1. Create a new Bitbucket account specifically for CodeRabbit and treat it as a service account. -2. Name the account "CodeRabbit". -3. If your Bitbucket workspace requires two-step verification, then you must also enable two-step verification on this - new account. -4. Generate an API Token to enable seamless integration between CodeRabbit and your Bitbucket repositories. - -We recommend creating a new user as a service account, associating this user to the workspace you'd like to install -CodeRabbit on, and providing CodeRabbit with the API token to allow access. During the installation process, CodeRabbit -will automatically configure the required webhook for seamless integration. - -:::note - -If you wish to change the review user, you must provide the API token for the new user who will post reviews and -comments. However, this requires manually removing the previous user from the projects and associated webhooks. Once -this is done, you will need to reinstall the CodeRabbit app for each project. - -::: - -### Recommendations - -- **Create a dedicated user for CodeRabbit** - This ensures the user is exclusively for CodeRabbit, allowing better - access control. -- **Use "CodeRabbit" as the username** - This makes the user easily recognizable for future reference. -- **Use a dedicated email address** - This helps in easy identification and management. -- **Use the CodeRabbit logo as the profile picture** - This further ensures easy recognition. You can download our logo - from [here](/img/integrations/logo.svg "download"). -- **Developer Access** Ensure the service account user has developer access to the projects that you wish to install - CodeRabbit on. - -#### Key Points to Remember - -- Code reviews will be attributed to the owner of the API token. - -#### Generating an API token - -Bitbucket provides an option to generate an API token for a new user. Follow these steps to generate the token: - -1. Log in using the user designated for CodeRabbit reviews. This user serves as a service account for managing reviews - and related activities. -2. Go to [API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens). -3. Click **Create API token with scopes**. -4. Enter a name easily recognizable for this API token usage and an expiration date based on your plan of using the - product. -5. On next step select **Bitbucket** -6. Ensure the following scopes are selected: - - read:account - - read:user:bitbucket - - write:issue:bitbucket - - read:issue:bitbucket - - read:workspace:bitbucket - - admin:project:bitbucket - - write:webhook:bitbucket - - read:webhook:bitbucket - - read:pipeline:bitbucket - - read:runner:bitbucket - - read:repository:bitbucket - - write:repository:bitbucket - - read:pullrequest:bitbucket - - write:pullrequest:bitbucket -7. Click **Create** -8. Note down the API token as it will only be displayed once. - -### Where to Provide CodeRabbit the API Token - -By default, if no API token is provided, CodeRabbit will prompt you to provide one during the installation process. -However, if you wish to provide the token beforehand, you can do so by navigating to the **Organization Settings** tab, -and selecting the **Bitbucket User** tab on the sidebar. Once entering the API token, the token will be validated and -saved for future use. - -You can confirm the correct user is being selected by verifying the user ID shown on the UI with the user ID of the -service account user you created. - ---- - -### Installing CodeRabbit into your Bitbucket Repositories - -1. Go to the [Repositories page](https://app.coderabbit.ai/settings/repositories) in the CodeRabbit app. -2. Select the checkbox next to the repositories where you want to install CodeRabbit. To install it on all repositories - at once, select the checkbox at the top. -3. Select **Install Repositories**. - -
    - Bitbucket Repo Install Modal -
    - -The webhook `https://coderabbit.ai/bitbucketHandler` will now be installed for the projects selected. - -
    - Bitbucket Webhook Example -
    - -### Troubleshooting - -:::note - -If you are experiencing issues with the webhook, such as CodeRabbit not being able to access the repository, or not -reviewing pull requests, you can manually delete the webhook to the repository. - -Then refresh the repository page in the CodeRabbit app and you can reinstall the webhook. - -If you cannot install the webhook please check that your Bitbucket user has the necessary permissions to install the -webhook and the API Token is properly configured. - -::: diff --git a/docs/platforms/bitbucket-cloud.mdx b/docs/platforms/bitbucket-cloud.mdx new file mode 100644 index 00000000..92d69500 --- /dev/null +++ b/docs/platforms/bitbucket-cloud.mdx @@ -0,0 +1,148 @@ +--- +title: "Bitbucket Cloud" +description: "Learn how to integrate CodeRabbit with Bitbucket Cloud." +sidebar_label: "Bitbucket Cloud" +sidebar_position: 6 +--- + +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" + +CodeRabbit integrates with Bitbucket Cloud to enhance code review and collaboration by: + + + +This guide will assist you in effectively integrating CodeRabbit with Bitbucket Cloud. + +## Configure API Token + +To enable CodeRabbit to interact with your Bitbucket repositories, an API token is required. This token grants the necessary permissions for interacting with the Bitbucket merge request and discussion APIs. + +Create a new Bitbucket account specifically for CodeRabbit and treat it as a service account, + <>Name the account "CodeRabbit", + <>If your Bitbucket workspace requires two-step verification, then you must also enable two-step verification on this new account, + <>Generate an API Token to enable seamless integration between CodeRabbit and your Bitbucket repositories + ]} +/> + +We recommend creating a new user as a service account, associating this user to the workspace you'd like to install CodeRabbit on, and providing CodeRabbit with the API token to allow access. During the installation process, CodeRabbit will automatically configure the required webhook for seamless integration. + + +If you wish to change the review user, you must provide the API token for the new user who will post reviews and comments. However, this requires manually removing the previous user from the projects and associated webhooks. Once this is done, you will need to reinstall the CodeRabbit app for each project. + + +### Recommendations + +Create a dedicated user for CodeRabbit - This ensures the user is exclusively for CodeRabbit, allowing better access control, + <>Use "CodeRabbit" as the username - This makes the user easily recognizable for future reference, + <>Use a dedicated email address - This helps in easy identification and management, + <>Use the CodeRabbit logo as the profile picture - This further ensures easy recognition. You can download our logo from here, + <>Developer Access Ensure the service account user has developer access to the projects that you wish to install CodeRabbit on + ]} +/> + +### Key Points to Remember + + + +### Generating an API token + +Bitbucket provides an option to generate an API token for a new user. Follow these steps to generate the token: + +Log in using the user designated for CodeRabbit reviews. This user serves as a service account for managing reviews and related activities, + <>Go to API Tokens, + <>Click Create API token with scopes, + <>Enter a name easily recognizable for this API token usage and an expiration date based on your plan of using the product, + <>On next step select Bitbucket, + <>Ensure the following scopes are selected: + , + <>Click Create, + <>Note down the API token as it will only be displayed once + ]} +/> + +### Where to Provide CodeRabbit the API Token + +By default, if no API token is provided, CodeRabbit will prompt you to provide one during the installation process. However, if you wish to provide the token beforehand, you can do so by navigating to the **Organization Settings** tab, and selecting the **Bitbucket User** tab on the sidebar. Once entering the API token, the token will be validated and saved for future use. + +You can confirm the correct user is being selected by verifying the user ID shown on the UI with the user ID of the service account user you created. + +--- + +### Installing CodeRabbit into your Bitbucket Repositories + +Go to the Repositories page in the CodeRabbit app, + <>Select the checkbox next to the repositories where you want to install CodeRabbit. To install it on all repositories at once, select the checkbox at the top, + <>Select Install Repositories + ]} +/> + +
    + Bitbucket Repo Install Modal +
    + +The webhook `https://coderabbit.ai/bitbucketHandler` will now be installed for the projects selected. + +
    + Bitbucket Webhook Example +
    + +### Troubleshooting + + +If you are experiencing issues with the webhook, such as CodeRabbit not being able to access the repository, or not reviewing pull requests, you can manually delete the webhook to the repository. + +Then refresh the repository page in the CodeRabbit app and you can reinstall the webhook. + +If you cannot install the webhook please check that your Bitbucket user has the necessary permissions to install the webhook and the API Token is properly configured. + \ No newline at end of file diff --git a/docs/platforms/github-com.md b/docs/platforms/github-com.mdx similarity index 73% rename from docs/platforms/github-com.md rename to docs/platforms/github-com.mdx index 60d919d7..7ceddec7 100644 --- a/docs/platforms/github-com.md +++ b/docs/platforms/github-com.mdx @@ -5,13 +5,22 @@ sidebar_label: GitHub.com sidebar_position: 1 --- +import InfoBox from "../../src/components/InfoBox" +import BlockQuote from "../../src/components/BlockQuote" +import Tip from "../../src/components/Tip" +import Note from "../../src/components/Note" + This is a step-by-step guide to integrate CodeRabbit with your GitHub repositories. -> **CodeRabbit** is an AI code reviewer designed to ease the challenges of code review, supporting repository maintainers and teams. It reviews your PRs and provides concise summaries, identifies potential issues, and offers insights that might be missed during manual reviews. +
    +**CodeRabbit** is an AI code reviewer designed to ease the challenges of code review, supporting repository maintainers and teams. It reviews your PRs and provides concise summaries, identifies potential issues, and offers insights that might be missed during manual reviews. +
    ## How CodeRabbit Works? -> CodeRabbit integrates with GitHub, automating the code review process from the moment a pull request is created. +
    +CodeRabbit integrates with GitHub, automating the code review process from the moment a pull request is created. +
    It preprocesses the PR content, builds context, leverages Large Language Models for analysis, and then post-processes the AI response before posting the review back to GitHub. This streamlined workflow ensures thorough AI-powered code reviews without manual intervention. @@ -19,6 +28,7 @@ It preprocesses the PR content, builds context, leverages Large Language Models ## Let's Integrate CodeRabbit with GitHub + ### 1. Accessing CodeRabbit Visit the [CodeRabbit login](https://app.coderabbit.ai/login?free-trial) page. You'll see all the authentication options, select "**Login with GitHub**" to proceed. @@ -29,7 +39,9 @@ Visit the [CodeRabbit login](https://app.coderabbit.ai/login?free-trial) page. Y When you choose **Login with GitHub** in step1, you'll be prompted to authorize CodeRabbit. -> This step grants the necessary permissions for CodeRabbit to interact with your repositories and pull requests. +
    +This step grants the necessary permissions for CodeRabbit to interact with your repositories and pull requests. +
    ![Authorization Login](/img/integrations/authorization-codeRabbit.png) @@ -47,9 +59,9 @@ Here, you can add repositories and configure CodeRabbit config settings for each ![CodeRabbit Dashboard](/img/integrations/codeRabbit-dashboard.png) -:::tip + If you opt to authorize all repositories during setup, CodeRabbit will automatically include any new repositories you create on GitHub in the future. This saves you the hassle of manual additions down the line. -::: + ### 5. CodeRabbit Configuration @@ -57,15 +69,15 @@ You can configure CodeRabbit through a YAML file or using the [App's UI](https:/ You can tailor CodeRabbit's functionality using the `.coderabbit.yaml` file, which you place directly in your GitHub repository. This file mirrors the options available in the CodeRabbit user interface, with each setting in the YAML corresponding to a specific toggle in the UI. Configure CodeRabbit either through the coderabbit.yaml file or the interface, depending on your preference. -:::note - + If a `.coderabbit.yaml` file exists in your GitHub repository, it takes precedence over any UI settings. Choose either the YAML file or UI configuration - you don't need to use both. **Refer CodeRabbit YAML schema [here](https://storage.googleapis.com/coderabbit_public_assets/schema.v2.json)** - -::: + Once your `.coderabbit.yaml` file is prepared according to your needs, simply place it in your GitHub repository, and you're all set — CodeRabbit is now integrated. -> When a pull request is created targeting the master branch, CodeRabbit automatically initiates its review process. It analyzes the changes and generates a summary and walkthrough of the modifications. The specific feedback and analysis provided by CodeRabbit are determined by the options you've configured in your YAML file. +
    +When a pull request is created targeting the master branch, CodeRabbit automatically initiates its review process. It analyzes the changes and generates a summary and walkthrough of the modifications. The specific feedback and analysis provided by CodeRabbit are determined by the options you've configured in your YAML file. +
    Let's see a few examples of CodeRabbit's review comments from a specific pull request in one of the projects. @@ -97,7 +109,9 @@ Also, check out the response when asked for what improvements can be done on the In addition to providing reviews and summaries, **CodeRabbit** can also detect configuration issues. -> For example, I accidentally set up both CodeRabbit Pro (The process we've been discussing) and the open-source version (Refer to [different config process](https://github.com/coderabbitai/ai-pr-reviewer?tab=readme-ov-file#install-instructions)) in my repository at the same time. +
    +For example, I accidentally set up both CodeRabbit Pro (The process we've been discussing) and the open-source version (Refer to [different config process](https://github.com/coderabbitai/ai-pr-reviewer?tab=readme-ov-file#install-instructions)) in my repository at the same time. +
    CodeRabbit automatically detects and alerts you about configuration conflicts. @@ -109,8 +123,12 @@ CodeRabbit generates detailed statistics and test plans for each pull request. ![Test Plan by CodeRabbit](/img/integrations/test-plan.png) -> CodeRabbit also allows you to configure **custom review instructions** based on your organization's needs, in case you want it to follow specific guidelines beyond the standard review, to learn more on [adding custom review instructions](/guides/review-instructions) +
    +CodeRabbit also allows you to configure **custom review instructions** based on your organization's needs, in case you want it to follow specific guidelines beyond the standard review, to learn more on [adding custom review instructions](/guides/review-instructions) +
    Whether you manage a popular repository or are working on a smaller project, whether it's hosted on **GitLab, GitHub, or self-hosted GitHub or GitLab**, CodeRabbit can help streamline your development process. This AI Code Review assistant is designed to save you time by automating code reviews and offering insightful feedback. -> Explore, Experiment, Discover how [CodeRabbit](https://docs.coderabbit.ai/) can streamline your code review process using AI. +
    +Explore, Experiment, Discover how [CodeRabbit](https://docs.coderabbit.ai/) can streamline your code review process using AI. +
    \ No newline at end of file diff --git a/docs/platforms/github-enterprise-server.md b/docs/platforms/github-enterprise-server.md deleted file mode 100644 index 733607cb..00000000 --- a/docs/platforms/github-enterprise-server.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: Integrating CodeRabbit with GitHub Enterprise Server -description: Learn how to integrate CodeRabbit with your GitHub Enterprise Server. -sidebar_label: GitHub Enterprise Server -sidebar_position: 3 ---- - -:::info - -This page is for GitHub Enterprise Server (Self-Hosted) users only. -If you're using `github.com`, [log in to CodeRabbit](https://app.coderabbit.ai) -and add your repositories from there - -::: - -This page guides you through the process of integrating your Self-Managed GitHub -with CodeRabbit. - -To initiate the integration, we require specific information. This is essential -for the initial setup of CodeRabbit within your domain. Once this setup is -complete, you can log in directly. - -### **Step 1: Getting Started** - -**Visit CodeRabbit:** Visit our [Login](https://app.coderabbit.ai/login?free-trial) page and -select Self-Hosted GitHub - -![CodeRabbit login page](/img/integrations/login-self-hosted-github.png) - -On this page, enter the URL of your self-managed GitHub instance and click -submit. Once, you submit, we check our database for a record of your -organization and if we find an existing one, we will start the login process. - -![Self-hosted gitHub enterprise connection page for CodeRabbit](/img/integrations/self-hosted-github-host-url.png) - -If the self-managed GitHub instance is not found, you will be required to enter -more details for the onboarding. - -### **Step 2: GitHub OAuth App** - -Navigate to your GitHub Enterprise Server (Self-Hosted) Instance and follow the -steps below to -[create an OAuth App](https://docs.github.com/en/enterprise-server@latest/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app): - -1. Sign in to your GitHub Enterprise account. -2. In the upper-right corner of any page, click your profile photo, then click - **Settings**. -3. In the left sidebar, click **Developer settings** > **OAuth Apps**. -4. Click **New OAuth App**. -5. Set the following fields: - - **Application name**: `CodeRabbit OAuth` - - **Homepage URL**: `https://coderabbit.ai` - - **Application description**: - `OAuth application for signing into CodeRabbit` - - **Authorization callback URL**: `https://app.coderabbit.ai/login` -6. Click **Register application**. - -![GitHub Create OAuth App](/img/integrations/github-create-oauth-app.png) - -Once the OAuth App has been created, click on **Generate a new client secret** -under the 'Client secrets' section and copy the secret as it will be visible -once only - -Keep the following details handy: - -- Client ID -- Client secret - -![GitHub OAuth Client ID & Secret](/img/integrations/github-oauth-client-id-secret.png) - -### **Step 3: GitHub App** - -Navigate to your GitHub Enterprise Server (Self-Hosted) Instance and follow the -steps below to -[create a GitHub App](https://docs.github.com/en/enterprise-server@latest/apps/creating-github-apps/registering-a-github-app/registering-a-github-app): - -1. Sign in to your GitHub Enterprise account. -2. In the upper-right corner of any page, click your profile photo, then click **Settings**. -3. In the left sidebar, click **Developer settings** > **GitHub Apps** -4. Click **New GitHub App**. -5. Set the following fields: - - **GitHub App name**: `CodeRabbit` - - **Description**: `GitHub App for CodeRabbit` - - **Homepage URL**: `https://coderabbit.ai` - - **Callback URL**: `https://app.coderabbit.ai/login` - - **Request user authorization (OAuth) during installation**: `true` - - **Webhook Active**: `true` - - **Webhook URL**: `https://app.coderabbit.ai/githubHandler` - - **Webhook secret**: Use a secure string and keep it handy. - - **Permissions**: - - **Repository permissions**: - - **Actions**: Read-only - - **Checks**: Read-only - - **Contents**: Read and write - - **Commit statuses**: Read and write - - **Discussions**: Read-only - - **Issues**: Read and write - - **Metadata**: Read-only - - **Pull requests**: Read and write - - **Organization permissions**: - - **Members**: Read-only - - **Events**: - - Meta - - Issue comment - - Issues - - Label - - Public - - Pull request - - Pull request review - - Pull request review comment - - Pull request review thread - - Push - - Release - - **Where can this GitHub App be installed?**: Select `Any account` -6. Click **Create GitHub App**. - -Once the GitHub App has been created, click on **Generate a new client secret** -under the 'Client secrets' section and copy the secret as it will be visible -once only. - -Scroll down and click on **Generate a private key** under the 'Private keys' -section and download the PEM file. - -Keep the following details handy: - -- App ID -- Client ID -- Client secret -- Webhook secret -- Private key - -![GitHub App Client ID & Secret](/img/integrations/github-app-client-id-secret.png) - -We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. - -### **Step 4: CodeRabbit UI Onboarding** - -Submit the details that were accumulated in previous steps: - -- Host URL of your GitHub instance -- OAuth Client ID -- OAuth Client Secret -- GitHub App ID -- GitHub App Client ID -- GitHub App Client Secret -- GitHub App Webhook Secret -- GitHub App Private Key - -Click on Submit and the login process will be initiated. On subsequent visits, -your setup will be automatically detected, allowing for direct login. - -### **Step 5: Install the GitHub App** - -Navigate to the GitHub App that was created from your GitHub Enterprise Server -(self-hosted) instance and click on the **Install App** tab. Then, install the -GitHub App to your organization(s). - -:::warning - -If you performed this step before Step 4, the installation event likely will -have failed, and you will need to re-send the installation event. -Navigate to the **Advanced** tab in the GitHub App and click on the -**Redeliver** button for the failed `installation.created` event. - -::: - -### **Step 6: Whitelist CodeRabbit IP address** - -Use this CodeRabbit IP if your instance requires IP whitelisting -`35.222.179.152/32` and `34.170.211.100/32`. - -VPN tunneling is available as an add-on package. Please reach out to us at -[support@coderabbit.ai](mailto:support@coderabbit.ai) if you are interested. - -### **FAQ** - -#### Who should create the OAuth App and GitHub App? - -The OAuth App and GitHub App should be created by a user with administrative -privileges on the GitHub Enterprise Server instance. This user will be responsible for managing the integration with CodeRabbit. - -#### I see an error when trying to log in to CodeRabbit. What should I do? - -If you encounter an error during the login process, please ensure that: - -- The OAuth App and GitHub App are correctly configured with the right URLs and permissions. -- The browser local storage and cookies related to CodeRabbit are cleared. - -If the issue persists, contact our support team. diff --git a/docs/platforms/github-enterprise-server.mdx b/docs/platforms/github-enterprise-server.mdx new file mode 100644 index 00000000..b8e5be99 --- /dev/null +++ b/docs/platforms/github-enterprise-server.mdx @@ -0,0 +1,187 @@ +--- +title: Integrating CodeRabbit with GitHub Enterprise Server +description: Learn how to integrate CodeRabbit with GitHub Enterprise Server. +sidebar_label: GitHub Enterprise Server +sidebar_position: 3 +--- + +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" + + +This page is for GitHub Enterprise Server (Self-Hosted) users only. If you're using `github.com`, [log in to CodeRabbit](https://app.coderabbit.ai) and add your repositories from there + + +This page guides you through the process of integrating your Self-Managed GitHub with CodeRabbit. + +To initiate the integration, we require specific information. This is essential for the initial setup of CodeRabbit within your domain. Once this setup is complete, you can log in directly. + +### **Step 1: Getting Started** + +**Visit CodeRabbit:** Visit our [Login](https://app.coderabbit.ai/login?free-trial) page and select Self-Hosted GitHub + +![CodeRabbit login page](/img/integrations/login-self-hosted-github.png) + +On this page, enter the URL of your self-managed GitHub instance and click submit. Once, you submit, we check our database for a record of your organization and if we find an existing one, we will start the login process. + +![Self-hosted gitHub enterprise connection page for CodeRabbit](/img/integrations/self-hosted-github-host-url.png) + +If the self-managed GitHub instance is not found, you will be required to enter more details for the onboarding. + +### **Step 2: GitHub OAuth App** + +Navigate to your GitHub Enterprise Server (Self-Hosted) Instance and follow the steps below to [create an OAuth App](https://docs.github.com/en/enterprise-server@latest/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app): + +Sign in to your GitHub Enterprise account, + <>In the upper-right corner of any page, click your profile photo, then click Settings, + <>In the left sidebar, click Developer settings OAuth Apps, + <>Click New OAuth App, + <>Set the following fields: + Application name: CodeRabbit OAuth, + <>Homepage URL: https://coderabbit.ai, + <>Application description: OAuth application for signing into CodeRabbit, + <>Authorization callback URL: https://app.coderabbit.ai/login + ]} + />, + <>Click Register application + ]} +/> + +![GitHub Create OAuth App](/img/integrations/github-create-oauth-app.png) + +Once the OAuth App has been created, click on **Generate a new client secret** under the 'Client secrets' section and copy the secret as it will be visible once only. + +Keep the following details handy: + + + +![GitHub OAuth Client ID & Secret](/img/integrations/github-oauth-client-id-secret.png) + +### **Step 3: GitHub App** + +Navigate to your GitHub Enterprise Server (Self-Hosted) Instance and follow the steps below to [create a GitHub App](https://docs.github.com/en/enterprise-server@latest/apps/creating-github-apps/registering-a-github-app/registering-a-github-app): + +Sign in to your GitHub Enterprise account, + <>In the upper-right corner of any page, click your profile photo, then click Settings, + <>In the left sidebar, click Developer settings GitHub Apps, + <>Click New GitHub App, + <>Set the following fields: + GitHub App name: CodeRabbit, + <>Description: GitHub App for CodeRabbit, + <>Homepage URL: https://coderabbit.ai, + <>Callback URL: https://app.coderabbit.ai/login, + <>Request user authorization (OAuth) during installation: true, + <>Webhook Active: true, + <>Webhook URL: https://app.coderabbit.ai/githubHandler, + <>Webhook secret: Use a secure string and keep it handy, + <>Permissions: + Repository permissions: + Actions: Read-only, + <>Checks: Read-only, + <>Contents: Read and write, + <>Commit statuses: Read and write, + <>Discussions: Read-only, + <>Issues: Read and write, + <>Metadata: Read-only, + <>Pull requests: Read and write + ]} + />, + <>Organization permissions: + Members: Read-only + ]} + />, + <>Events: + + ]} + />, + <>Where can this GitHub App be installed?: Select Any account + ]} + />, + <>Click Create GitHub App + ]} +/> + +Once the GitHub App has been created, click on **Generate a new client secret** under the 'Client secrets' section and copy the secret as it will be visible once only. + +Scroll down and click on **Generate a private key** under the 'Private keys' section and download the PEM file. + +Keep the following details handy: + + + +![GitHub App Client ID & Secret](/img/integrations/github-app-client-id-secret.png) + +We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. + +### **Step 4: CodeRabbit UI Onboarding** + +Submit the details that were accumulated in previous steps: + + + +Click on Submit and the login process will be initiated. On subsequent visits, your setup will be automatically detected, allowing for direct login. diff --git a/docs/platforms/gitlab-com.mdx b/docs/platforms/gitlab-com.mdx index c276cd35..6f040418 100644 --- a/docs/platforms/gitlab-com.mdx +++ b/docs/platforms/gitlab-com.mdx @@ -5,11 +5,20 @@ sidebar_label: GitLab.com sidebar_position: 2 --- +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" +import ChatBubble from "../../src/components/ChatBubble" + CodeRabbit integrates with GitLab to enhance code review and collaboration by: -- Automatically initiating code reviews for newly created merge requests. -- Displaying review comments and suggestions directly on merge requests. -- Enabling seamless interaction with the CodeRabbit bot for real-time feedback and assistance. + This guide will assist you in effectively integrating CodeRabbit with SaaS GitLab. @@ -17,8 +26,13 @@ This guide will assist you in effectively integrating CodeRabbit with SaaS GitLa To enable CodeRabbit to interact with your GitLab repositories, an access token is required. This token grants the necessary permissions for interacting with the Merge Requests and Discussions APIs. - 1. Personal Access Token (PAT): You can create a new GitLab account specifically for CodeRabbit, name it “CodeRabbit” and treat it as a service account. Then generate a PAT from it where PAT will enable seamless integration between CodeRabbit and your GitLab repositories. - 2. Group Access Token: If your organization uses GitLab Premium or Ultimate, you can generate a Group Access Token. This option automatically creates a bot user associated with the group for managing access and posting reviews. +Personal Access Token (PAT): You can create a new GitLab account specifically for CodeRabbit, name it "CodeRabbit" and treat it as a service account. Then generate a PAT from it where PAT will enable seamless integration between CodeRabbit and your GitLab repositories., + <>Group Access Token: If your organization uses GitLab Premium or Ultimate, you can generate a Group Access Token. This option automatically creates a bot user associated with the group for managing access and posting reviews. + ]} +/> ### Personal Access Token @@ -32,11 +46,9 @@ We recommend creating a new user as a service account, associating this user to />
    -:::note - -If you wish to change the review user, you must provide the access token for the new user who will post reviews and comments. However, this requires manually removing the previous user from the projects and associated webhooks. Once this is done, you will need to reinstall the CodeRabbit app for each project. - -::: + +If you wish to change the review user, you must provide the access token for the new user who will post reviews and comments. However, this requires manually removing the previous user from the projects and associated webhooks. Once this is done, you will need to reinstall the CodeRabbit app for each project. +
    Create a dedicated user for CodeRabbit - This ensures the user is exclusively for CodeRabbit, allowing better access control, + <>Use "CodeRabbit" as the username - This makes the user easily recognizable for future reference, + <>Use a dedicated email address - This helps in easy identification and management, + <>Use the CodeRabbit logo as the profile picture - This further ensures easy recognition. You can download our logo from here, + <>Ensure Developer Access - Ensure the dedicated user has (at least) Developer access to the group or projects that you wish to install CodeRabbit on + ]} +/> #### Key Points to Remember -- Personal access tokens have expiration dates. Ensure the expiration date **covers the duration** of your intended use of CodeRabbit. -- Code reviews will be attributed to the owner of the personal access token. -- If the personal access token expires, you can add a new one via the CodeRabbit UI: - - Navigate to the **GitLab User** page in the sidebar. - - Enter the new Access token, and click the **Update** button on the page. +Personal access tokens have expiration dates. Ensure the expiration date covers the duration of your intended use of CodeRabbit, + <>Code reviews will be attributed to the owner of the personal access token, + <>If the personal access token expires, you can add a new one via the CodeRabbit UI: + Navigate to the GitLab User page in the sidebar, + <>Enter the new Access token, and click the Update button on the page + ]} + /> + ]} +/> #### Generating a Personal Access Token GitLab provides an option to generate a personal access token for a new user. Follow these steps to generate the token: -1. Log in using the user designated for CodeRabbit reviews. This user serves as a service account for managing reviews and related activities. -2. Select your avatar on the left sidebar. -3. Choose **Edit Profile**. -4. Select **Access Tokens** from the left sidebar. -5. Click [Add New Token.](https://gitlab.com/-/user_settings/personal_access_tokens) -6. Enter a name and an expiry date for the token. -7. If no expiry date is entered, it defaults to 365 days from the current date. -8. Ensure the following scopes are selected: `api`, `read_api`, `read_user`. -9. Click **Create Personal Access Token** -10. Note down the token as it will only be displayed once. +Log in using the user designated for CodeRabbit reviews. This user serves as a service account for managing reviews and related activities, + <>Select your avatar on the left sidebar, + <>Choose Edit Profile, + <>Select Access Tokens from the left sidebar, + <>Click Add New Token, + <>Enter a name and an expiry date for the token, + <>If no expiry date is entered, it defaults to 365 days from the current date, + <>Ensure the following scopes are selected: api, read_api, read_user, + <>Click Create Personal Access Token, + <>Note down the token as it will only be displayed once + ]} +/>
    By default, GitLab restricts this option to users on the Premium or Ultimate tiers. - -::: + #### Generating a Group Access Token -1. Navigate to the group you wish to install CodeRabbit on. -2. Select **Settings** from the left sidebar. -3. Select **Access Tokens** within the Settings heading. -4. Create a Group Access Token. -5. Ensure the following scopes are selected: `api`. -6. Ensure Developer Access is provided. +Navigate to the group you wish to install CodeRabbit on, + <>Select Settings from the left sidebar, + <>Select Access Tokens within the Settings heading, + <>Create a Group Access Token, + <>Ensure the following scopes are selected: api, + <>Ensure Developer Access is provided + ]} +/> --- @@ -119,9 +152,14 @@ You can confirm the correct user is being selected by verifying the user ID show ### Installing CodeRabbit into your GitLab Repositories -1. Go to the [Repositories page](https://app.coderabbit.ai/settings/repositories) in the CodeRabbit app. -2. Select the checkbox next to the repositories where you want to install CodeRabbit. To install it on all repositories at once, select the checkbox at the top. -3. Select **Install Repositories**. +Go to the Repositories page in the CodeRabbit app, + <>Select the checkbox next to the repositories where you want to install CodeRabbit. To install it on all repositories at once, select the checkbox at the top, + <>Select Install Repositories + ]} +/>
    +Troubleshooting Webhook Issues: If you are experiencing issues with the webhook, such as coderabbit not being able to access the repository, or not reviewing pull requests, you can manually delete the webhook to the repository. Then refresh the repository page in the CodeRabbit app and you can reinstall the webhook. If you cannot install the webhook please check that your GitLab user has the necessary permissions to install the webhook and the PAT is not expired. - -::: + diff --git a/docs/platforms/platforms.md b/docs/platforms/platforms.md deleted file mode 100644 index d4cb1748..00000000 --- a/docs/platforms/platforms.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Integrate with Git platforms -description: Overview of CodeRabbit's supported Git platforms. ---- - -CodeRabbit supports various Git platforms to provide code review for your repositories. For the cloud-hosted Git platforms, you can [login][login] to CodeRabbit and add your repositories. The following platforms are supported: - -## GitHub - -| Host | Support | -| ------------------------ | ---------------------------------------- | -| GitHub.com | [Supported](github-com.md) | -| GitHub Enterprise Server | [Supported](github-enterprise-server.md) | - -## GitLab - -| Host | Support | -| ------------------- | ---------------------------------- | -| GitLab.com | [Supported](gitlab-com.mdx) | -| GitLab Self Managed | [Supported](self-hosted-gitlab.md) | - -## Azure DevOps - -| Host | Support | -| ------------ | ---------------------------- | -| Azure DevOps | [Supported](azure-devops.md) | - -## Bitbucket - -| Host | Support | -| -------------------- | ---------------------------------------- | -| Bitbucket Datacenter | [Supported](../self-hosted/bitbucket.md) | -| Bitbucket Cloud | [Supported](./bitbucket-cloud.md) | - -[login]: https://app.coderabbit.ai/login?free-trial diff --git a/docs/platforms/platforms.mdx b/docs/platforms/platforms.mdx new file mode 100644 index 00000000..6b29443c --- /dev/null +++ b/docs/platforms/platforms.mdx @@ -0,0 +1,77 @@ +--- +title: Integrate with Git platforms +description: Overview of CodeRabbit's supported Git platforms. +--- + +import Table from "@site/src/components/Table" + +CodeRabbit supports various Git platforms to provide code review for your repositories. For the cloud-hosted Git platforms, you can [login][login] to CodeRabbit and add your repositories. The following platforms are supported: + +## GitHub + + + +## GitLab + +
    + +## Azure DevOps + +
    + +## Bitbucket + +
    + +[login]: https://app.coderabbit.ai/login?free-trial diff --git a/docs/platforms/self-hosted-gitlab.md b/docs/platforms/self-hosted-gitlab.md deleted file mode 100644 index 3fa18a71..00000000 --- a/docs/platforms/self-hosted-gitlab.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Integrating CodeRabbit for Self-Managed GitLab -description: Learn how to integrate CodeRabbit with your Self-Managed GitLab instance. -sidebar_label: Self-Managed GitLab -sidebar_position: 4 ---- - -This page guides you through the process of integrating your Self-Managed GitLab -with CodeRabbit. - -To initiate the integration, we require specific information. This is essential -for the initial setup of CodeRabbit within your domain. Once this setup is -complete, you can log in directly using the OAuth2 flow. - -CodeRabbit supports GitLab `16.x` and above. Version `15.x` may experience -unexpected issues such as review comments not being posted or the sign-up -process not working at all. While we won't block the integration, we recommend -upgrading your GitLab instance to obtain the intended experience. - -### **Step 1: Getting Started** - -**Visit CodeRabbit:** Visit our [Login](https://app.coderabbit.ai/login?free-trial) page and -select Self-Hosted GitLab - -![CodeRabbit login](/img/integrations/login-self-hosted-gitlab.png) - -### Step 2: Enter your Self-Managed GitLab URL - -On this page, enter the URL of your self-managed GitLab instance and click -submit. Once, you submit, we check our database for a record of your -organization and if we find an existing one, we are starting the login process. - -![Self-hosted Gitlab enterprise connection page](/img/integrations/self-hosted-gitlab-host-url.png) - -If the self-managed GitLab instance is not found, we initiate the onboarding -process, which can be either manual or automated. - -### **Step 3: Onboarding Manual or Automated** - -#### 1. Automated onboarding - -![Self-managed GitLab connection page](/img/integrations/automated-onboarding.png) - -#### **Why do we need the Admin Access Token?** - -Admin access token is required to set up a new CodeRabbit bot user within your -self-managed instance. The token is needed only once during the initial setup -process. Once the token is generated, you can set its minimum expiration period. -This is the standard approach used by other products in this category. This is -not automatically installing the CodeRabbit app across all projects. You will -add CodeRabbit manually on the projects you wish, as the next step. - -#### 2. Manual onboarding - -For the manual onboarding process we need to create the -[CodeRabbit user](#creating-coderabbit-user) and the -[OAuth2 GitLab application](#creating-oauth2-application). -![Self-managed GitLab connection page](/img/integrations/manual-onboarding.png) - -#### **Creating CodeRabbit user** - -This feature will work with any user from your organization, but we strongly -suggest creating a dedicated user called **CodeRabbitAI**. This ensures clarify -about which user is used for our application and allows for better fine-grained -access control. - -To create users in GitLab, log in with an instance admin account and follow the -steps provided in the -[GitLab documentation](https://docs.gitlab.com/ee/user/profile/account/create_accounts.html#create-users-in-admin-area). -After the user is created, you can retrieve the **User ID** from that user's -profile and generate an [**access token**](#generating-personal-access-token). -The access token is used to post reviews on merge requests. - -We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. - -#### **Creating OAuth2 application** - -For self-managed GitLab, we recommend creating an instance-wide application -unless you want the reviews to be limited to a single group or user. - -Please follow the steps outlined in the -[GitLab documentation](https://docs.gitlab.com/ee/integration/oauth_provider.html#create-an-instance-wide-application) -for creating the application. - -Requirements: - -1. Scopes: `api read_user email openid` -2. Callback URL: `https://app.coderabbit.ai/login` - -#### **Generating Personal Access token** - -GitLab offers an option to generate a personal access token for adding a new -user and setting up the application in the self-managed instance. To generate -the token, please follow the process outlined below: - -1. Login to your self-hosted instance. For - [automated onboarding](#1-automated-onboarding) ensure you have admin rights. -2. On the left sidebar, select your avatar. -3. Select Edit profile. -4. On the left sidebar, select Access Tokens. -5. Select Add new token. -6. Enter a name and expiry date for the token. We need this for the initial - setup, so the minimum expiry time is sufficient. -7. If you do not enter an expiry date, the expiry date is automatically set to - 365 days later than the current date. -8. Make sure, you select the scopes: `api read_api read_user` -9. Select Create personal access token. -10. Please note down this token as this will be visible one time only - -![GitLab personal access token configuration page](/img/integrations/admin-access-token.png) - -### **Step 4: Paste the details and click submit** - -- Submit the form. -- We will handle the setup process for you. -- On subsequent visits, your setup will be automatically detected, allowing for - direct login. ![CodeRabbit authentication options page](/img/integrations/self-hosted-page.png) - -### **Step 5: Whitelist CodeRabbit IP address** - -Use this CodeRabbit IP if your instance requires IP whitelisting -`35.222.179.152/32` and `34.170.211.100/32`. - -VPN tunneling is available as an add-on package. Please reach out to us at -[support@coderabbit.ai](mailto:support@coderabbit.ai) if you are interested. diff --git a/docs/platforms/self-hosted-gitlab.mdx b/docs/platforms/self-hosted-gitlab.mdx new file mode 100644 index 00000000..083885b6 --- /dev/null +++ b/docs/platforms/self-hosted-gitlab.mdx @@ -0,0 +1,110 @@ +--- +title: Integrating CodeRabbit for Self-Managed GitLab +description: Learn how to integrate CodeRabbit with your Self-Managed GitLab instance. +sidebar_label: Self-Managed GitLab +sidebar_position: 4 +--- + +import InfoBox from "../../src/components/InfoBox" +import ListItems from "../../src/components/ListItems" +import ChatBubble from "../../src/components/ChatBubble" + +This page guides you through the process of integrating your Self-Managed GitLab with CodeRabbit. + +To initiate the integration, we require specific information. This is essential for the initial setup of CodeRabbit within your domain. Once this setup is complete, you can log in directly using the OAuth2 flow. + +CodeRabbit supports GitLab `16.x` and above. Version `15.x` may experience unexpected issues such as review comments not being posted or the sign-up process not working at all. While we won't block the integration, we recommend upgrading your GitLab instance to obtain the intended experience. + +### **Step 1: Getting Started** + +**Visit CodeRabbit:** Visit our [Login](https://app.coderabbit.ai/login?free-trial) page and select Self-Hosted GitLab + +![CodeRabbit login](/img/integrations/login-self-hosted-gitlab.png) + +### Step 2: Enter your Self-Managed GitLab URL + +On this page, enter the URL of your self-managed GitLab instance and click submit. Once, you submit, we check our database for a record of your organization and if we find an existing one, we are starting the login process. + +![Self-hosted Gitlab enterprise connection page](/img/integrations/self-hosted-gitlab-host-url.png) + +If the self-managed GitLab instance is not found, we initiate the onboarding process, which can be either manual or automated. + +### **Step 3: Onboarding Manual or Automated** + +#### 1. Automated onboarding + +![Self-managed GitLab connection page](/img/integrations/automated-onboarding.png) + +#### **Why do we need the Admin Access Token?** + +Admin access token is required to set up a new CodeRabbit bot user within your self-managed instance. The token is needed only once during the initial setup process. Once the token is generated, you can set its minimum expiration period. This is the standard approach used by other products in this category. This is not automatically installing the CodeRabbit app across all projects. You will add CodeRabbit manually on the projects you wish, as the next step. + +#### 2. Manual onboarding + +For the manual onboarding process we need to create the [CodeRabbit user](#creating-coderabbit-user) and the [OAuth2 GitLab application](#creating-oauth2-application). + +![Self-managed GitLab connection page](/img/integrations/manual-onboarding.png) + +#### **Creating CodeRabbit user** + +This feature will work with any user from your organization, but we strongly suggest creating a dedicated user called **CodeRabbitAI**. This ensures clarity about which user is used for our application and allows for better fine-grained access control. + +To create users in GitLab, log in with an instance admin account and follow the steps provided in the [GitLab documentation](https://docs.gitlab.com/ee/user/profile/account/create_accounts.html#create-users-in-admin-area). After the user is created, you can retrieve the **User ID** from that user's profile and generate an [**access token**](#generating-personal-access-token). The access token is used to post reviews on merge requests. + +We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. + +#### **Creating OAuth2 application** + +For self-managed GitLab, we recommend creating an instance-wide application unless you want the reviews to be limited to a single group or user. + +Please follow the steps outlined in the [GitLab documentation](https://docs.gitlab.com/ee/integration/oauth_provider.html#create-an-instance-wide-application) for creating the application. + +Requirements: + +Scopes: api read_user email openid, + <>Callback URL: https://app.coderabbit.ai/login + ]} +/> + +#### **Generating Personal Access token** + +GitLab offers an option to generate a personal access token for adding a new user and setting up the application in the self-managed instance. To generate the token, please follow the process outlined below: + +Login to your self-hosted instance. For automated onboarding ensure you have admin rights, + <>On the left sidebar, select your avatar, + <>Select Edit profile, + <>On the left sidebar, select Access Tokens, + <>Select Add new token, + <>Enter a name and expiry date for the token. We need this for the initial setup, so the minimum expiry time is sufficient, + <>If you do not enter an expiry date, the expiry date is automatically set to 365 days later than the current date, + <>Make sure, you select the scopes: api read_api read_user, + <>Select Create personal access token, + <>Please note down this token as this will be visible one time only + ]} +/> + +![GitLab personal access token configuration page](/img/integrations/admin-access-token.png) + +### **Step 4: Paste the details and click submit** + +Submit the form, + <>We will handle the setup process for you, + <>On subsequent visits, your setup will be automatically detected, allowing for direct login + ]} +/> + +![CodeRabbit authentication options page](/img/integrations/self-hosted-page.png) + +### **Step 5: Whitelist CodeRabbit IP address** + +Use this CodeRabbit IP if your instance requires IP whitelisting: `35.222.179.152/32` and `34.170.211.100/32`. + +VPN tunneling is available as an add-on package. Please reach out to us at [support@coderabbit.ai](mailto:support@coderabbit.ai) if you are interested. \ No newline at end of file diff --git a/docs/self-hosted/azure-devops.md b/docs/self-hosted/azure-devops.mdx similarity index 63% rename from docs/self-hosted/azure-devops.md rename to docs/self-hosted/azure-devops.mdx index c8926b0f..3a13635b 100644 --- a/docs/self-hosted/azure-devops.md +++ b/docs/self-hosted/azure-devops.mdx @@ -5,16 +5,22 @@ description: Instructions to self-host CodeRabbit and integrate it with Azure De sidebar_position: 3 --- -:::note +import ListItems from '@site/src/components/ListItems/ListItems'; +import Note from '@site/src/components/Note/Note'; +import DarkCodeBlock from '@site/src/components/DarkCodeBlock/DarkCodeBlock'; + + The self-hosted option is only available for CodeRabbit Enterprise customers with 500 user seats or more. Please contact [CodeRabbit Sales](mailto:sales@coderabbit.ai) to learn more about the CodeRabbit Enterprise plan. -::: + ## Create an Azure DevOps User -- **Username**: Set the username to "CodeRabbit" for easier identification (optional). -- **Profile Image**: Use the CodeRabbitAI logo for the user image (optional). +Username: Set the username to "CodeRabbit" for easier identification (optional)., + <>Profile Image: Use the CodeRabbitAI logo for the user image (optional). +]} /> We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. @@ -28,30 +34,34 @@ Generate a personal access token for the CodeRabbit user to be added in the `.en **Necessary Scopes**: -- `Code` - Full -- `Work Items` - Read, write, and manage -- `Build` - Read +Code - Full, + <>Work Items - Read, write, and manage, + <>Build - Read +]} /> Consult official CodeRabbitAI documentation for a detailed [guide](https://docs.coderabbit.ai/platforms/azure-devops#generating-a-personal-access-token) on creating personal access tokens. ## Add the necessary webhooks to each project -1. **Navigate to project's Service Hooks Page**: Go to the service hooks configuration page in the desired Azure DevOps project. - -2. **Add the following webhooks:** - - 1. Pull request created - 2. Pull request updated - 3. Pull request commented on - -3. **Add Webhook URL**: Enter the URL pointing to the CodeRabbit service, followed by `/azure_webhooks` (e.g., `http://127.0.0.1:8080/azure_webhooks`) for each webhook. +Navigate to project's Service Hooks Page: Go to the service hooks configuration page in the desired Azure DevOps project., + <>Add the following webhooks: + Pull request created, + <>Pull request updated, + <>Pull request commented on + ]} /> + , + <>Add Webhook URL: Enter the URL pointing to the CodeRabbit service, followed by /azure_webhooks (e.g., http://127.0.0.1:8080/azure_webhooks) for each webhook. +]} /> ## Prepare an `.env` file Create an `.env` file with the following content: -```bash -# if using OpenAI + +{`# if using OpenAI LLM_PROVIDER=openai LLM_TIMEOUT=360000 OPENAI_API_KEYS= @@ -128,39 +138,41 @@ LINEAR_PAT=[] ENABLE_WEB_SEARCH=[true] PERPLEXITY_API_KEY=[] -YAML_CONFIG=[] -``` +YAML_CONFIG=[]`} + -:::note + -- If you are using Azure OpenAI, verify that the model deployment names are in the .env file. -- Values marked with [] are not optional to provide. -- You can generate `CODERABBIT_API_KEY` from CodeRabbit UI -> Organizations Settings -> API Keys. -- `YAML_CONFIG` is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the [CodeRabbit YAML configuration](/docs/getting-started/configure-coderabbit.md) file. It requires the entire YAML file to be in an escaped string format, for example, `YAML_CONFIG="key1: value1\nkey2: value2"`. You can use [Escape YAML](https://escapeyaml.dev/) to generate the escaped string. +If you are using Azure OpenAI, verify that the model deployment names are in the .env file., + <>Values marked with [] are not optional to provide., + <>You can generate CODERABBIT_API_KEY from CodeRabbit UI {"->"} Organizations Settings {"->"} API Keys., + <>YAML_CONFIG is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the CodeRabbit YAML configuration file. It requires the entire YAML file to be in an escaped string format, for example, YAML_CONFIG="key1: value1\nkey2: value2". You can use Escape YAML to generate the escaped string. +]} /> -::: + ## Pull the CodeRabbit Docker image Authenticate and pull the Docker image using the provided credentials file: -```bash -cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev -docker pull /coderabbit-agent:latest -``` + +{`cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev +docker pull /coderabbit-agent:latest`} + ### Verify the image is up You can query `/health` endpoint to verify that the `coderabbit-agent` service is up and running. -```bash -curl 127.0.0.1:8080/health -``` + +{`curl 127.0.0.1:8080/health`} + ## Host the image You can host the image on a server, serverless function, or container environment and expose port `8080`. Run the Docker image with the equivalent command on your chosen platform, ensuring you replace the `.env` file path with the path to your actual `.env` file: -```bash -docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest -``` + +{`docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest`} + diff --git a/docs/self-hosted/bitbucket.md b/docs/self-hosted/bitbucket.mdx similarity index 64% rename from docs/self-hosted/bitbucket.md rename to docs/self-hosted/bitbucket.mdx index bccbb251..ccc50a9c 100644 --- a/docs/self-hosted/bitbucket.md +++ b/docs/self-hosted/bitbucket.mdx @@ -5,16 +5,22 @@ description: Instructions to self-host CodeRabbit and integrate it with Bitbuck sidebar_position: 4 --- -:::note +import ListItems from '@site/src/components/ListItems/ListItems'; +import Note from '@site/src/components/Note/Note'; +import DarkCodeBlock from '@site/src/components/DarkCodeBlock/DarkCodeBlock'; + + The self-hosted option is only available for CodeRabbit Enterprise customers with 500 user seats or more. Please contact [CodeRabbit Sales](mailto:sales@coderabbit.ai) to learn more about the CodeRabbit Enterprise plan. -::: + ## Create a Bitbucket User -- **Username**: Set the username to "CodeRabbit" for easier identification (optional). -- **Profile Image**: Use the CodeRabbitAI logo for the user image (optional). +Username: Set the username to "CodeRabbit" for easier identification (optional)., + <>Profile Image: Use the CodeRabbitAI logo for the user image (optional). +]} /> We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. @@ -22,8 +28,10 @@ We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the prof Add the CodeRabbit user to each project where you want CodeRabbit to post reviews, with permissions to: -- Post reviews -- Open pull requests +Post reviews, + <>Open pull requests +]} /> ## Create a Personal Access Token for CodeRabbit user @@ -31,19 +39,24 @@ Generate a personal access token for the CodeRabbit user to be added in the `.en ## Add a webhook to each project -1. **Navigate to Webhook Settings**: Go to the repository settings and locate the webhooks configuration page. -2. **Configure Events**: Enable the following Pull Request events: - - "Opened" - - "Modified" - - "Comment Added" -3. **Add Webhook URL**: Enter the URL pointing to the CodeRabbit service, followed by `/bitbucket_server_webhooks` (e.g., `http://127.0.0.1:8080/bitbucket_server_webhooks`). +Navigate to Webhook Settings: Go to the repository settings and locate the webhooks configuration page., + <>Configure Events: Enable the following Pull Request events: + "Opened", + <>"Modified", + <>"Comment Added" + ]} /> + , + <>Add Webhook URL: Enter the URL pointing to the CodeRabbit service, followed by /bitbucket_server_webhooks (e.g., http://127.0.0.1:8080/bitbucket_server_webhooks). +]} /> ## Prepare a `.env` file Create a `.env` file with the following content: -```bash -# if using OpenAI + +{`# if using OpenAI LLM_PROVIDER=openai LLM_TIMEOUT=360000 OPENAI_API_KEYS= @@ -123,39 +136,40 @@ LINEAR_PAT=[] ENABLE_WEB_SEARCH=[true] PERPLEXITY_API_KEY=[] -YAML_CONFIG=[] -``` +YAML_CONFIG=[]`} + -:::note + -- If you are using Azure OpenAI, verify that the model deployment names are in the .env file. - Values marked with [] are optional and can be omitted if the feature is not needed. -- You can generate `CODERABBIT_API_KEY` from CodeRabbit UI -> Organizations Settings -> API Keys. -- `YAML_CONFIG` is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the [CodeRabbit YAML configuration](/docs/getting-started/configure-coderabbit.md) file. It requires the entire YAML file to be in an escaped string format, for example, `YAML_CONFIG="key1: value1\nkey2: value2"`. You can use [Escape YAML](https://escapeyaml.dev/) to generate the escaped string. +If you are using Azure OpenAI, verify that the model deployment names are in the .env file. Values marked with [] are optional and can be omitted if the feature is not needed., + <>You can generate CODERABBIT_API_KEY from CodeRabbit UI {"->"} Organizations Settings {"->"} API Keys., + <>YAML_CONFIG is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the CodeRabbit YAML configuration file. It requires the entire YAML file to be in an escaped string format, for example, YAML_CONFIG="key1: value1\nkey2: value2". You can use Escape YAML to generate the escaped string. +]} /> -::: + ## Pull the CodeRabbit Docker image Authenticate and pull the Docker image using the provided credentials file: -```bash -cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev -docker pull us-docker.pkg.dev/coderabbitprod/self-hosted/coderabbit-agent:latest -``` + +{`cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev +docker pull us-docker.pkg.dev/coderabbitprod/self-hosted/coderabbit-agent:latest`} + ### Verify the image is up You can query `/health` endpoint to verify that the `coderabbit-agent` service is up and running. -```bash -curl 127.0.0.1:8080/health -``` + +{`curl 127.0.0.1:8080/health`} + ## Host the image You can host the image on a server, serverless function, or container environment and expose port `8080`. Run the Docker image with the equivalent command on your chosen platform, ensuring you replace the `.env` file path with the path to your actual `.env` file: -```bash -docker run --env-file .env --publish 127.0.0.1:8080:8080 us-docker.pkg.dev/coderabbitprod/self-hosted/coderabbit-agent:latest -``` + +{`docker run --env-file .env --publish 127.0.0.1:8080:8080 us-docker.pkg.dev/coderabbitprod/self-hosted/coderabbit-agent:latest`} + diff --git a/docs/self-hosted/github.md b/docs/self-hosted/github.mdx similarity index 75% rename from docs/self-hosted/github.md rename to docs/self-hosted/github.mdx index 6e2b27c1..164d4c40 100644 --- a/docs/self-hosted/github.md +++ b/docs/self-hosted/github.mdx @@ -5,56 +5,73 @@ description: Instructions to self-host CodeRabbit and integrate it with GitHub. sidebar_position: 1 --- -:::note +import ListItems from "../../src/components/ListItems" +import Note from "../../src/components/Note" +import DarkCodeBlock from "../../src/components/DarkCodeBlock" + The self-hosted option is only available for CodeRabbit Enterprise customers with 500 user seats or more. Please contact [CodeRabbit Sales](mailto:sales@coderabbit.ai) to learn more about the CodeRabbit Enterprise plan. - -::: + ## Create a GitHub App Set the following Repository permissions: -- Checks: Read-only -- Contents: Read and write -- Commit statuses: Read and write -- Discussions: Read-only -- Issues: Read & write -- Metadata: Read-only -- Pull requests: Read & write -- Actions: Read-only + Set the following Organization permissions: -- Members: Read-only + Set the following events: -- Meta -- Issue comment -- Issues -- Label -- Public -- Pull request -- Pull request review -- Pull request review comment -- Pull request review thread -- Push -- Release + We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. ## Gather information from the GitHub App -- App ID -- Client ID -- Client Secret -- Webhook Secret + ## Prepare an `.env` file -```bash -# if using OpenAI +{`# if using OpenAI LLM_PROVIDER=openai LLM_TIMEOUT=360000 OPENAI_API_KEYS= @@ -141,46 +158,37 @@ LINEAR_PAT=[] ENABLE_WEB_SEARCH=[true] PERPLEXITY_API_KEY=[] -YAML_CONFIG=[] -``` - -:::note +YAML_CONFIG=[]`} + - If you are using Azure OpenAI, verify that the model deployment names are in the .env file. - Values marked with [] are optional to provide. - For `GITHUB_APP_PEM_FILE`, flatten the PEM file by replacing newlines with `\n`. -- For `GITHUB_HOSTNAME`, use GitHub Enterprise server's hostname, for example, “github.acme-inc.com” +- For `GITHUB_HOSTNAME`, use GitHub Enterprise server's hostname, for example, "github.acme-inc.com" - You can generate `CODERABBIT_API_KEY` from CodeRabbit UI -> Organizations Settings -> API Keys. - When `ENABLE_LEARNINGS` is set to `true`, CodeRabbit will use `CODERABBIT_API_KEY` to store learnings on our servers. - `YAML_CONFIG` is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the [CodeRabbit YAML configuration](/docs/getting-started/configure-coderabbit.md) file. It requires the entire YAML file to be in an escaped string format, for example, `YAML_CONFIG="key1: value1\nkey2: value2"`. You can use [Escape YAML](https://escapeyaml.dev/) to generate the escaped string. - -::: + ## Pull the CodeRabbit Docker image Using the credentials file shared with you, first authenticate and then pull the image. -```bash -cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev -docker pull /coderabbit-agent:latest -``` +{`cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev +docker pull /coderabbit-agent:latest`} ## Host the image -You can choose to host it on a server, serverless function, or a container environment and expose the port “8080”. Run the Docker image with the equivalent of the following command on the platform of your choice, replacing the “.env” file with the path to your “.env” file: +You can choose to host it on a server, serverless function, or a container environment and expose the port "8080". Run the Docker image with the equivalent of the following command on the platform of your choice, replacing the ".env" file with the path to your ".env" file: -```bash -docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest -``` +{`docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest`} ### Verify the image is up You can query `/health` endpoint to verify that the `coderabbit-agent` service is up and running. -```bash -curl 127.0.0.1:8080/health -``` +{`curl 127.0.0.1:8080/health`} ## Install the GitHub App -You can install the GitHub App on your GitHub organization or user account and point the Webhook URL to the hosted CodeRabbit instance, for example, `http://127.0.0.1:8080/github_webhooks`. GitHub will send events to the CodeRabbit instance. +You can install the GitHub App on your GitHub organization or user account and point the Webhook URL to the hosted CodeRabbit instance, for example, `http://127.0.0.1:8080/github_webhooks`. GitHub will send events to the CodeRabbit instance. \ No newline at end of file diff --git a/docs/self-hosted/gitlab.md b/docs/self-hosted/gitlab.mdx similarity index 62% rename from docs/self-hosted/gitlab.md rename to docs/self-hosted/gitlab.mdx index 395d93fc..331db545 100644 --- a/docs/self-hosted/gitlab.md +++ b/docs/self-hosted/gitlab.mdx @@ -5,16 +5,22 @@ description: Instructions to self-host CodeRabbit and integrate it with GitLab. sidebar_position: 2 --- -:::note +import ListItems from '@site/src/components/ListItems/ListItems'; +import Note from '@site/src/components/Note/Note'; +import DarkCodeBlock from '@site/src/components/DarkCodeBlock/DarkCodeBlock'; + + The self-hosted option is only available for CodeRabbit Enterprise customers with 500 user seats or more. Please contact [CodeRabbit Sales](mailto:sales@coderabbit.ai) to learn more about the CodeRabbit Enterprise plan. -::: + ## Create a GitLab User -- **Username**: Set the username to "CodeRabbit" for easier identification (optional). -- **Profile Image**: Use the CodeRabbitAI logo for the user image (optional). +Username: Set the username to "CodeRabbit" for easier identification (optional)., + <>Profile Image: Use the CodeRabbitAI logo for the user image (optional). +]} /> We recommend using the CodeRabbit [logo](/img/integrations/logo.png) as the profile picture to ensures easy recognition. @@ -34,55 +40,59 @@ Consult official CodeRabbitAI documentation for a detailed [guide](https://docs. ## Add a webhook to each project -1. **Navigate to Add Webhook Page**: Go to the webhook configuration page in the desired GitLab project. -2. **Add Webhook URL**: Enter the URL pointing to the CodeRabbit service, followed by `/gitlab_webhooks` (e.g., `http://127.0.0.1:8080/gitlab_webhooks`). -3. **Generate and Save Secret Token**: Generate a secret token, add it to the webhook, and store it securely. This will be needed for the `.env` file as `GITLAB_WEBHOOK_SECRET` (you can use a single secret token for all projects). -4. **Select triggers**: - - - Push events - - Comments - - Issues events - - Merge request events +Navigate to Add Webhook Page: Go to the webhook configuration page in the desired GitLab project., + <>Add Webhook URL: Enter the URL pointing to the CodeRabbit service, followed by /gitlab_webhooks (e.g., http://127.0.0.1:8080/gitlab_webhooks)., + <>Generate and Save Secret Token: Generate a secret token, add it to the webhook, and store it securely. This will be needed for the .env file as GITLAB_WEBHOOK_SECRET (you can use a single secret token for all projects)., + <>Select triggers: + Push events, + <>Comments, + <>Issues events, + <>Merge request events + ]} /> + +]} /> ## Add Webhook Using a Script We have a convenient [script](/code/gitlab-webhook.sh) to help you add webhooks to a project or all projects under a group in a GitLab instance. -```bash -# Make sure the script is executable: -chmod +x gitlab-webhook.sh -``` + +{`# Make sure the script is executable: +chmod +x gitlab-webhook.sh`} + Example usage: -```bash -# PAT example (header auto-detected) + +{`# PAT example (header auto-detected) export GITLAB_TOKEN="glpat-xxxxx" -./gitlab-add-webhook.sh \ - -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ +./gitlab-add-webhook.sh \\ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \\ -s "mySecret" -p 42 # PAT example (explicit header) -./gitlab-add-webhook.sh \ - -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ - -s "mySecret" -g "mygroup/mysubgroup/myproject" \ - -t "glpat-xxxxx" \ +./gitlab-add-webhook.sh \\ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \\ + -s "mySecret" -g "mygroup/mysubgroup/myproject" \\ + -t "glpat-xxxxx" \\ -A "PRIVATE-TOKEN" # OAuth token with explicit header -./gitlab-add-webhook.sh \ - -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ - -s "mySecret" -g "company/backend" \ - -t "eyJhbGciOi..." \ - -A "Authorization: Bearer" -``` +./gitlab-add-webhook.sh \\ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \\ + -s "mySecret" -g "company/backend" \\ + -t "eyJhbGciOi..." \\ + -A "Authorization: Bearer"`} + ## Prepare a `.env` file Create a `.env` file with the following content: -```bash -# if using OpenAI + +{`# if using OpenAI LLM_PROVIDER=openai LLM_TIMEOUT=360000 OPENAI_API_KEYS= @@ -168,39 +178,41 @@ LINEAR_PAT=[] ENABLE_WEB_SEARCH=[true] PERPLEXITY_API_KEY=[] -YAML_CONFIG=[] -``` +YAML_CONFIG=[]`} + -:::note + -- If you are using Azure OpenAI, verify that the model deployment names are in the .env file. -- Values marked with [] are not optional to provide. -- You can generate `CODERABBIT_API_KEY` from CodeRabbit UI -> Organizations Settings -> API Keys. -- `YAML_CONFIG` is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the [CodeRabbit YAML configuration](/docs/getting-started/configure-coderabbit.md) file. It requires the entire YAML file to be in an escaped string format, for example, `YAML_CONFIG="key1: value1\nkey2: value2"`. You can use [Escape YAML](https://escapeyaml.dev/) to generate the escaped string. +If you are using Azure OpenAI, verify that the model deployment names are in the .env file., + <>Values marked with [] are not optional to provide., + <>You can generate CODERABBIT_API_KEY from CodeRabbit UI {"->"} Organizations Settings {"->"} API Keys., + <>YAML_CONFIG is an optional configuration file that can be used to customize CodeRabbit's behavior at the deployment level. It takes the same format as the CodeRabbit YAML configuration file. It requires the entire YAML file to be in an escaped string format, for example, YAML_CONFIG="key1: value1\nkey2: value2". You can use Escape YAML to generate the escaped string. +]} /> -::: + ## Pull the CodeRabbit Docker image Authenticate and pull the Docker image using the provided credentials file: -```bash -cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev -docker pull /coderabbit-agent:latest -``` + +{`cat coderabbit.json | docker login -u _json_key --password-stdin us-docker.pkg.dev +docker pull /coderabbit-agent:latest`} + ### Verify the image is up You can query `/health` endpoint to verify that the coderabbit-agent service is up and running. -```bash -curl 127.0.0.1:8080/health -``` + +{`curl 127.0.0.1:8080/health`} + ## Host the image You can host the image on a server, serverless function, or container environment and expose port `8080`. Run the Docker image with the equivalent command on your chosen platform, ensuring you replace the `.env` file path with the path to your actual `.env` file: -```bash -docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest -``` + +{`docker run --env-file .env --publish 127.0.0.1:8080:8080 /coderabbit-agent:latest`} + diff --git a/src/components/BlockQuote/BlockQuote.module.css b/src/components/BlockQuote/BlockQuote.module.css new file mode 100644 index 00000000..1f77e21e --- /dev/null +++ b/src/components/BlockQuote/BlockQuote.module.css @@ -0,0 +1,33 @@ +.blockquote { + border-left: 3px solid #9B9B9B; + padding: 1rem 1.5rem; + margin: 1.2rem 0; + color: var(--ifm-color-content); + position: relative; +} + +.blockquote p { + margin: 0; + line-height: 1.6; +} + +.blockquote p:not(:last-child) { + margin-bottom: 1rem; +} + +/* Responsive design */ +@media (max-width: 768px) { + .blockquote { + padding: 0.8rem 1.2rem; + margin: 1rem 0; + border-left-width: 2px; + } +} + +@media (max-width: 480px) { + .blockquote { + padding: 0.7rem 1rem; + margin: 0.8rem 0; + border-left-width: 2px; + } +} \ No newline at end of file diff --git a/src/components/BlockQuote/BlockQuote.tsx b/src/components/BlockQuote/BlockQuote.tsx new file mode 100644 index 00000000..36c68724 --- /dev/null +++ b/src/components/BlockQuote/BlockQuote.tsx @@ -0,0 +1,14 @@ +import React from "react" +import styles from "./BlockQuote.module.css" + +interface BlockQuoteProps { + children: React.ReactNode +} + +const BlockQuote: React.FC = ({ children }) => ( +
    + {children} +
    +) + +export default BlockQuote \ No newline at end of file diff --git a/src/components/BlockQuote/index.ts b/src/components/BlockQuote/index.ts new file mode 100644 index 00000000..ecadbbc2 --- /dev/null +++ b/src/components/BlockQuote/index.ts @@ -0,0 +1 @@ +export { default } from "./BlockQuote" \ No newline at end of file diff --git a/src/components/ChatBubble/ChatBubble.module.css b/src/components/ChatBubble/ChatBubble.module.css index 61f961ce..4842d276 100644 --- a/src/components/ChatBubble/ChatBubble.module.css +++ b/src/components/ChatBubble/ChatBubble.module.css @@ -8,4 +8,70 @@ font-size: 0.98em; white-space: pre-wrap; word-break: break-word; + position: relative; +} + +.content { + padding-right: 2.5rem; +} + +.copyButton { + position: absolute; + top: 0.75rem; + right: 0.75rem; + background: rgba(255, 255, 255, 0.1); + border: none; + border-radius: 4px; + color: var(--imf-text-color); + cursor: pointer; + padding: 0.5rem; + opacity: 0.7; + transition: opacity 0.2s ease, background 0.2s ease; + display: flex; + align-items: center; + justify-content: center; +} + +.copyButton:hover { + opacity: 1; + background: rgba(255, 255, 255, 0.2); +} + +.copyButton:active { + transform: scale(0.95); +} + +/* Responsive design */ +@media (max-width: 768px) { + .chatBubble { + padding: 0.8rem 1rem; + font-size: 0.95rem; + } + + .content { + padding-right: 2.2rem; + } + + .copyButton { + top: 0.6rem; + right: 0.6rem; + padding: 0.4rem; + } +} + +@media (max-width: 480px) { + .chatBubble { + padding: 0.7rem 0.8rem; + font-size: 0.9rem; + } + + .content { + padding-right: 2rem; + } + + .copyButton { + top: 0.5rem; + right: 0.5rem; + padding: 0.3rem; + } } diff --git a/src/components/ChatBubble/ChatBubble.tsx b/src/components/ChatBubble/ChatBubble.tsx index 02850637..823c3445 100644 --- a/src/components/ChatBubble/ChatBubble.tsx +++ b/src/components/ChatBubble/ChatBubble.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { useState } from "react" import styles from "./ChatBubble.module.css" export default function ChatBubble({ @@ -6,5 +6,40 @@ export default function ChatBubble({ }: { children: React.ReactNode }) { - return
    {children}
    + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + try { + const textContent = typeof children === 'string' + ? children + : (children as any)?.props?.children || children?.toString() || ''; + await navigator.clipboard.writeText(textContent); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy text: ', err); + } + }; + + return ( +
    +
    {children}
    + +
    + ) } diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.module.css b/src/components/DarkCodeBlock/DarkCodeBlock.module.css index e424a52c..bc4118ad 100644 --- a/src/components/DarkCodeBlock/DarkCodeBlock.module.css +++ b/src/components/DarkCodeBlock/DarkCodeBlock.module.css @@ -3,11 +3,16 @@ border-radius: 8px; overflow: hidden; background-color: #1a1a1a; - border: none; + border: 1px solid #333; font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace; position: relative; } +/* Add border for dark theme */ +[data-theme="dark"] .codeBlock { + border: 1px solid #444; +} + .codeHeader { background-color: #1a1a1a; padding: 0.75rem 1rem; @@ -40,6 +45,10 @@ white-space: pre; } +.shortCode { + padding-bottom: 0.5rem; +} + .codeLine { display: block; min-height: 1.6rem; @@ -119,6 +128,10 @@ padding: 0.75rem; padding-bottom: 3rem; } + + .shortCode { + padding-bottom: 0.3rem; + } .copyButton { font-size: 0.7rem; diff --git a/src/components/DarkCodeBlock/DarkCodeBlock.tsx b/src/components/DarkCodeBlock/DarkCodeBlock.tsx index 47a4775c..0428c180 100644 --- a/src/components/DarkCodeBlock/DarkCodeBlock.tsx +++ b/src/components/DarkCodeBlock/DarkCodeBlock.tsx @@ -29,6 +29,7 @@ const DarkCodeBlock: React.FC = ({ const highlightedCode = useMemo(() => { const highlightCode = (code: string, lang: string) => { const lines = code.trim().split('\n'); + const isShortCode = lines.length <= 3; return lines.map((line, index) => { if (lang === 'python') { @@ -148,6 +149,9 @@ const DarkCodeBlock: React.FC = ({ return highlightCode(children, language); }, [children, language, KEYWORDS]); + const lineCount = children.trim().split('\n').length; + const isShortCode = lineCount <= 3; + return (
    {title && ( @@ -156,7 +160,7 @@ const DarkCodeBlock: React.FC = ({
    )}
    -
    +        
               
                 {highlightedCode}
               
    diff --git a/src/components/InfoBox/InfoBox.module.css b/src/components/InfoBox/InfoBox.module.css
    index afa9212b..4a64d05f 100644
    --- a/src/components/InfoBox/InfoBox.module.css
    +++ b/src/components/InfoBox/InfoBox.module.css
    @@ -17,3 +17,20 @@
     .infoBox a:hover {
     	text-decoration: underline;
     }
    +
    +/* Responsive design */
    +@media (max-width: 768px) {
    +	.infoBox {
    +		padding: 0.6em;
    +		border-radius: 10px;
    +		font-size: 0.95rem;
    +	}
    +}
    +
    +@media (max-width: 480px) {
    +	.infoBox {
    +		padding: 0.5em;
    +		border-radius: 8px;
    +		font-size: 0.9rem;
    +	}
    +}
    diff --git a/src/components/ListItems/ListItems.module.css b/src/components/ListItems/ListItems.module.css
    index e671f8cb..f724eb21 100644
    --- a/src/components/ListItems/ListItems.module.css
    +++ b/src/components/ListItems/ListItems.module.css
    @@ -3,7 +3,38 @@
     	border-radius: 8px;
     	padding: 1.3rem;
     	margin: 0.8rem 0;
    -	border: 2px solid var(--ifm-background-color-secondary);
    +}
    +
    +.crNestedList {
    +	margin: 0.5rem 0;
    +	padding: 0;
    +	background: none;
    +	border: none;
    +}
    +
    +.crNestedList .crFeatureList li {
    +	padding-left: 2rem;
    +}
    +
    +.crNestedList .crFeatureList li:before {
    +	left: 0.5rem;
    +}
    +
    +/* Second level nesting - square bullets */
    +.crNestedLevel2 li:before {
    +	border-radius: 0 !important;
    +	width: 0.3em !important;
    +	height: 0.3em !important;
    +	top: 0.65em !important;
    +	background: #333 !important;
    +}
    +
    +.crNestedList .crNestedLevel2 li {
    +	padding-left: 2.5rem;
    +}
    +
    +.crNestedList .crNestedLevel2 li:before {
    +	left: 0.7rem;
     }
     
     .crFeatureList {
    @@ -45,10 +76,10 @@
     	content: "";
     	position: absolute;
     	left: 0.3em;
    -	top: 0.5em;
    -	width: 0.6em;
    -	height: 0.6em;
    -	background: var(--imf-list-bullets-color);
    +	top: 0.6em;
    +	width: 0.4em;
    +	height: 0.4em;
    +	background: #333;
     	border-radius: 50%;
     	display: inline-block;
     }
    @@ -72,3 +103,58 @@
     .crOrderedList li a:hover {
     	text-decoration: underline;
     }
    +
    +/* Responsive design */
    +@media (max-width: 768px) {
    +	.crFeatureCard {
    +		padding: 1rem;
    +		margin: 0.6rem 0;
    +	}
    +	
    +	.crFeatureList li {
    +		padding-left: 1.5em;
    +		margin-bottom: 0.8em;
    +		font-size: 1rem;
    +	}
    +	
    +	.crOrderedList li {
    +		margin-bottom: 0.8em;
    +		font-size: 1rem;
    +		padding-left: 0.2em;
    +	}
    +	
    +	.crNestedList .crFeatureList li {
    +		padding-left: 1.8rem;
    +	}
    +	
    +	.crNestedList .crNestedLevel2 li {
    +		padding-left: 2.2rem;
    +	}
    +}
    +
    +@media (max-width: 480px) {
    +	.crFeatureCard {
    +		padding: 0.8rem;
    +		margin: 0.5rem 0;
    +	}
    +	
    +	.crFeatureList li {
    +		padding-left: 1.3em;
    +		margin-bottom: 0.7em;
    +		font-size: 0.95rem;
    +	}
    +	
    +	.crOrderedList li {
    +		margin-bottom: 0.7em;
    +		font-size: 0.95rem;
    +		padding-left: 0.15em;
    +	}
    +	
    +	.crNestedList .crFeatureList li {
    +		padding-left: 1.6rem;
    +	}
    +	
    +	.crNestedList .crNestedLevel2 li {
    +		padding-left: 2rem;
    +	}
    +}
    diff --git a/src/components/ListItems/ListItems.tsx b/src/components/ListItems/ListItems.tsx
    index 6f87105f..67231379 100644
    --- a/src/components/ListItems/ListItems.tsx
    +++ b/src/components/ListItems/ListItems.tsx
    @@ -5,20 +5,32 @@ interface ListItemsProps {
     	items: React.ReactNode[]
     	className?: string
     	orderedList?: boolean
    +	nested?: boolean
    +	nestingLevel?: number
     }
     
     export const ListItems: React.FC = ({
     	items,
     	className,
     	orderedList = false,
    +	nested = false,
    +	nestingLevel = 1,
     }) => {
     	const ListTag = orderedList ? "ol" : "ul"
    -	const listClassName = orderedList
    -		? styles.crOrderedList
    -		: styles.crFeatureList
    +	
    +	// Determine list class based on nesting level
    +	let listClassName = orderedList ? styles.crOrderedList : styles.crFeatureList
    +	if (nested && nestingLevel > 1) {
    +		listClassName = `${listClassName} ${styles.crNestedLevel2}`
    +	}
    +
    +	// Use different wrapper class for nested lists
    +	const wrapperClassName = nested 
    +		? `${styles.crNestedList} ${className || ""}`
    +		: `${styles.crFeatureCard} ${className || ""}`
     
     	return (
    -		
    +
    {items.map((item, index) => (
  • {item}
  • diff --git a/src/components/Note/Note.module.css b/src/components/Note/Note.module.css index e4f27ae6..87c13129 100644 --- a/src/components/Note/Note.module.css +++ b/src/components/Note/Note.module.css @@ -40,3 +40,76 @@ .note p { margin: 0rem; } + +/* Remove white background from ListItems inside Note - more aggressive approach */ +.note :global(.crFeatureCard) { + background: transparent !important; + background-color: transparent !important; + border: none !important; + padding: 0.5rem 0 !important; + margin: 0.5rem 0 !important; + box-shadow: none !important; +} + +/* Also target nested ListItems */ +.note :global(.crNestedList) { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} + +/* Force override CSS variables for ListItems inside Note */ +.note { + --imf-list-card-background-color: transparent; + --ifm-background-color-secondary: transparent; +} + +/* Target any div containing ListItems inside Note */ +.note div:has(:global(.crFeatureCard)) { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} + +/* Alternative approach - target all divs inside note that contain lists */ +.note > div { + background: inherit !important; + background-color: inherit !important; +} + +/* Responsive design */ +@media (max-width: 768px) { + .note { + padding: 0.8rem 1rem; + margin: 1rem 0; + font-size: 0.95rem; + } + + .icon { + width: 1.3em; + height: 1.3em; + margin-right: 0.4em; + } + + .title { + font-size: 0.95rem; + } +} + +@media (max-width: 480px) { + .note { + padding: 0.7rem 0.8rem; + margin: 0.8rem 0; + font-size: 0.9rem; + } + + .icon { + width: 1.2em; + height: 1.2em; + margin-right: 0.3em; + } + + .title { + font-size: 0.9rem; + } +} diff --git a/src/components/Table/Table.module.css b/src/components/Table/Table.module.css new file mode 100644 index 00000000..4ca57887 --- /dev/null +++ b/src/components/Table/Table.module.css @@ -0,0 +1,209 @@ +.tableContainer { + margin: 1.5rem 0; +} + +.platformSection { + margin-bottom: 2rem; +} + +.platformSection:last-child { + margin-bottom: 0; +} + +.platformTitle { + margin-bottom: 1rem; + color: var(--ifm-heading-color); + font-size: 1.5rem; + font-weight: 700; +} + +.titleSection { + background: #E8E8E8 !important; + border-bottom: none !important; + border-right: none !important; + border-left: none !important; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +.titleWithText { + padding: 1rem 1.5rem !important; + height: auto; +} + +.titleEmpty { + padding: 0 !important; + height: 10px !important; + line-height: 10px !important; +} + +.titleText { + color: var(--ifm-heading-color); + font-size: 1rem; + font-weight: 600; +} + +.titleRow { + background: #E8E8E8; +} + +.table { + display: table; + width: 100%; + border-collapse: separate; + border-spacing: 0; + background: transparent; + border: none; + table-layout: fixed; + border-radius: 4px; + overflow: hidden; +} + +.table th { + background: #ffffff; + color: var(--ifm-heading-color); + padding: 1rem 1.5rem; + text-align: left; + font-weight: 600; + font-size: 1rem; + border-bottom: 1px solid var(--ifm-color-emphasis-300); + border-right: 1px solid var(--ifm-color-emphasis-300); + border-top: none; + box-sizing: border-box; + margin: 0; +} + +.table th:last-child { + border-right: none; +} + +.table th:first-child { + border-left: none; +} + +.table thead { + background: #ffffff; +} + +.table td { + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--ifm-color-emphasis-300); + border-right: 1px solid var(--ifm-color-emphasis-300); + color: var(--ifm-color-content); + vertical-align: middle; + background: #ffffff; + box-sizing: border-box; +} + +.table td:last-child { + border-right: none; +} + +.table td:first-child { + border-left: none; +} + +.table tbody tr:last-child td { + border-bottom: none; +} + +.table tbody tr:hover { + background: var(--ifm-color-emphasis-50); +} + +.supportedStatus { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.supportIcon { + width: 20px; + height: 20px; + flex-shrink: 0; +} + +.supportText { + color: #5A9B8A; + font-weight: 500; +} + +/* Responsive design */ +@media (max-width: 768px) { + .table th, + .table td { + padding: 0.75rem 1rem; + font-size: 0.9rem; + } + + .platformTitle { + font-size: 1.25rem; + } + + .supportedStatus { + gap: 0.375rem; + } + + .supportIcon { + width: 18px; + height: 18px; + } + + .supportText { + font-size: 0.9rem; + } +} + +@media (max-width: 480px) { + .table th, + .table td { + padding: 0.5rem 0.75rem; + font-size: 0.85rem; + } + + .platformTitle { + font-size: 1.125rem; + } + + .supportIcon { + width: 16px; + height: 16px; + } + + .supportText { + font-size: 0.85rem; + } +} + +/* Dark mode adjustments */ +[data-theme="dark"] .table { + background: var(--ifm-background-color-secondary); + border-color: var(--ifm-color-emphasis-300); +} + +[data-theme="dark"] .table th { + background: var(--ifm-background-color-secondary); + border: none !important; +} + +[data-theme="dark"] .table td { + border: none !important; + background: var(--ifm-background-color-secondary); +} + +[data-theme="dark"] .titleSection { + background: var(--ifm-color-emphasis-200) !important; + border-bottom-color: var(--ifm-color-emphasis-300) !important; +} + +[data-theme="dark"] .titleRow { + background: var(--ifm-color-emphasis-200); +} + +[data-theme="dark"] .table tbody tr:hover { + background: var(--ifm-color-emphasis-100); +} + +[data-theme="dark"] .supportText { + color: #7CB3A3; +} \ No newline at end of file diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx new file mode 100644 index 00000000..7238fe3d --- /dev/null +++ b/src/components/Table/Table.tsx @@ -0,0 +1,89 @@ +import React from "react" +import styles from "./Table.module.css" + +interface SupportedStatusProps { + text: string + icon?: string +} + +const SupportedStatus: React.FC = ({ text, icon }) => { + return ( +
    + {icon && } + {text} +
    + ) +} + +interface TableColumn { + key: string + label: string +} + +interface TableRow { + [key: string]: React.ReactNode +} + +interface PlatformSection { + title: string + rows: TableRow[] +} + +interface TableProps { + columns: TableColumn[] + sections: PlatformSection[] + className?: string +} + +export const Table: React.FC = ({ + columns, + sections, + className, +}) => { + const columnWidth = `${100 / columns.length}%` + + return ( +
    + {sections.map((section, sectionIndex) => ( +
    +
    + + + + + + {columns.map((column) => ( + + ))} + + + + {section.rows.map((row, rowIndex) => ( + + {columns.map((column) => ( + + ))} + + ))} + +
    + {section.title && {section.title}} +
    + {column.label} +
    + {column.key === 'support' && typeof row[column.key] === 'string' && row[column.key] === 'Supported' ? ( + + ) : ( + row[column.key] + )} +
    +
    + ))} +
    + ) +} + +export default Table \ No newline at end of file diff --git a/src/components/Table/index.ts b/src/components/Table/index.ts new file mode 100644 index 00000000..f26095d5 --- /dev/null +++ b/src/components/Table/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Table" +export { Table } from "./Table" \ No newline at end of file diff --git a/src/components/Tip/Tip.module.css b/src/components/Tip/Tip.module.css new file mode 100644 index 00000000..f162e5ce --- /dev/null +++ b/src/components/Tip/Tip.module.css @@ -0,0 +1,84 @@ +.tip { + display: flex; + flex-direction: column; + align-items: flex-start; + background: #FFFCFB; + border: 2px solid #FFCEB6; + border-radius: 12px; + padding: 1rem 1.2rem; + margin: 1.2rem 0; + font-size: 1rem; +} + +.header { + display: flex; + align-items: center; + margin-bottom: 0.3em; +} + +.icon { + width: 1.5em; + height: 1.5em; + margin-right: 0.5em; + flex-shrink: 0; + color: #FF570A; +} + +.title { + font-weight: 600; + color: #FF570A; + font-size: 1rem; +} + +.content { + margin-top: 0.2em; + color: var(--ifm-color-content); +} + +.tip p { + margin: 0; + line-height: 1.6; +} + +.tip p:not(:last-child) { + margin-bottom: 1rem; +} + +/* Responsive design */ +@media (max-width: 768px) { + .tip { + padding: 0.8rem 1rem; + margin: 1rem 0; + font-size: 0.95rem; + border-radius: 10px; + } + + .icon { + width: 1.3em; + height: 1.3em; + margin-right: 0.4em; + } + + .title { + font-size: 0.95rem; + } +} + +@media (max-width: 480px) { + .tip { + padding: 0.7rem 0.8rem; + margin: 0.8rem 0; + font-size: 0.9rem; + border-radius: 8px; + } + + .icon { + width: 1.2em; + height: 1.2em; + margin-right: 0.3em; + } + + .title { + font-size: 0.9rem; + } +} \ No newline at end of file diff --git a/src/components/Tip/Tip.tsx b/src/components/Tip/Tip.tsx new file mode 100644 index 00000000..c9935925 --- /dev/null +++ b/src/components/Tip/Tip.tsx @@ -0,0 +1,20 @@ +import React from "react" +import styles from "./Tip.module.css" + +interface TipProps { + children: React.ReactNode +} + +const Tip: React.FC = ({ children }) => ( +
    +
    + + + + Tip +
    +
    {children}
    +
    +) + +export default Tip \ No newline at end of file diff --git a/src/components/Tip/index.ts b/src/components/Tip/index.ts new file mode 100644 index 00000000..78c619e8 --- /dev/null +++ b/src/components/Tip/index.ts @@ -0,0 +1 @@ +export { default } from "./Tip" \ No newline at end of file diff --git a/src/components/Warning/Warning.module.css b/src/components/Warning/Warning.module.css new file mode 100644 index 00000000..f49f80c7 --- /dev/null +++ b/src/components/Warning/Warning.module.css @@ -0,0 +1,119 @@ +.warning { + display: flex; + flex-direction: column; + align-items: flex-start; + background: #FFFEFB; + border: 2px solid #f1c232; + border-radius: 8px; + padding: 1rem 1.2rem; + margin: 1.2rem 0; + font-size: 1rem; +} + +.header { + display: flex; + align-items: center; + margin-bottom: 0.3em; +} + +.icon { + width: 1em; + height: 1em; + margin-right: 0.5em; + flex-shrink: 0; +} + +.title { + font-weight: 600; + color: #B38705; +} + +.text { + margin-top: 0.2em; + color: #333; +} + +.warning .text p { + margin: 0px; +} + +.warning a { + color: #B38705; +} + +.warning p { + margin: 0rem; +} + +/* Remove white background from ListItems inside Warning - more aggressive approach */ +.warning :global(.crFeatureCard) { + background: transparent !important; + background-color: transparent !important; + border: none !important; + padding: 0.5rem 0 !important; + margin: 0.5rem 0 !important; + box-shadow: none !important; +} + +/* Also target nested ListItems */ +.warning :global(.crNestedList) { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} + +/* Force override CSS variables for ListItems inside Warning */ +.warning { + --imf-list-card-background-color: transparent; + --ifm-background-color-secondary: transparent; +} + +/* Target any div containing ListItems inside Warning */ +.warning div:has(:global(.crFeatureCard)) { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} + +/* Alternative approach - target all divs inside warning that contain lists */ +.warning > div { + background: inherit !important; + background-color: inherit !important; +} + +/* Responsive design */ +@media (max-width: 768px) { + .warning { + padding: 0.8rem 1rem; + margin: 1rem 0; + font-size: 0.95rem; + } + + .icon { + width: 1.3em; + height: 1.3em; + margin-right: 0.4em; + } + + .title { + font-size: 0.95rem; + } +} + +@media (max-width: 480px) { + .warning { + padding: 0.7rem 0.8rem; + margin: 0.8rem 0; + font-size: 0.9rem; + } + + .icon { + width: 1.2em; + height: 1.2em; + margin-right: 0.3em; + } + + .title { + font-size: 0.9rem; + } +} \ No newline at end of file diff --git a/src/components/Warning/Warning.tsx b/src/components/Warning/Warning.tsx new file mode 100644 index 00000000..318ddba1 --- /dev/null +++ b/src/components/Warning/Warning.tsx @@ -0,0 +1,18 @@ +import React from "react" +import styles from "./Warning.module.css" + +interface WarningProps { + children: React.ReactNode +} + +const Warning: React.FC = ({ children }) => ( +
    +
    + Warning + Warning +
    +
    {children}
    +
    +) + +export default Warning \ No newline at end of file diff --git a/src/components/Warning/index.ts b/src/components/Warning/index.ts new file mode 100644 index 00000000..07e3da26 --- /dev/null +++ b/src/components/Warning/index.ts @@ -0,0 +1 @@ +export { default as Warning } from "./Warning" \ No newline at end of file diff --git a/static/img/Icons/Tip.png b/static/img/Icons/Tip.png new file mode 100644 index 0000000000000000000000000000000000000000..8cfb10cb9a2f964c0d6e665e3e7783bf4c78e30d GIT binary patch literal 487 zcmVKI8x;llB#v>g>L3e_v?Ivwz|n-pYVm7AZdb45ePIuxM>kJ>TPX05 zEkM)-m1^dZwf3PWm;rv0A*a<2m*F;_4Ax61%>e409yZ|0 zEiEVJP@4D&iHyED8^FmJm>N^q_YxWz(6uZRPAk0~uG321*(ArYDu}xOiE*q_3qzTKfUmCQZyr(g;k!b{6MyzC7w0K2xM(mu$=F7^p z%}uzBhH~w5+1=QR$Sg dSUAIf*&8)nl+;vnfn@*y002ovPDHLkV1itb&v5_% literal 0 HcmV?d00001 diff --git a/static/img/Icons/Vector.png b/static/img/Icons/Vector.png new file mode 100644 index 0000000000000000000000000000000000000000..cec316fe6f0a965ff1893711f195b0346d370d54 GIT binary patch literal 478 zcmV<40U`d0P)200009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPhAH($JAgN*suvbL10=lF4i`xEk ztk#!1rz%dAYY;H6C?ngXzjXW0CXJ%kntBl8oUacXYk!@9&$ZF-ygpa)!#rgB1KX3l U(^&uO&j0`b07*qoM6N<$f>&Y0cmMzZ literal 0 HcmV?d00001 diff --git a/static/img/Icons/Warning.png b/static/img/Icons/Warning.png new file mode 100644 index 0000000000000000000000000000000000000000..73aecee6c65fb7ba80b4954115e3eb77f2487fac GIT binary patch literal 1631 zcmV-l2B7(gP)@~0drDELIAGL9O(c600d`2O+f$vv5yPnMnBDo$>`(wLEiElAEiElAEspWm{GgA2;4lmv z#3!8U<&@iM~q;!Cc4@Q2?|?pEL!&KYnaJT8RfZw}CZd>oA!-^WMeDXhUEJaCMV zC9j?u55Z&pLHG(B!zm9$?+YNgq0R}wKXhp-JLQ1^+n%e=*+B9R9Ksm`ewc@+!1;;B zsnO;9AOc5l#(?6BXs>U~Aun{ofS2M2=Vig{0zIY#;OO3=}G3WVhWBy3E_n)c4dt<1M0{Yo%L%cYvch1P}aQeS_>#v z42Xe)k}ViG9?KRLoBPd_k~PfRT9Y+a4Cu3jmMub}6p5Z`0fCS;7*K4+_`M-7#EGt`d;IKWT#%+}UYxO`39O4G=h?`#=PvVRbFx3kWZbg|3PB@1( z6Y>Vv$UJXqTGj+mBN#Y1F}@2Napri~y}c5K>!)v6nyL*pJi(GyMk8XLOfM0s7nWKg zbf|3#U;Y*r%6A|5@Y+Ag{Tzcq-eyvoClkv+-R1vU42Xe)agatq3>*P?7rA51CyJ-r zDDS9{HE$?c1B}0@OV-q4Kv{Re0~k0=Mn{x2Yzt(bTvz$uxB=1o#QJqA8%OW^aS~sE zVUB-|-vCi~#Tik@ezI``1}s@n<34yps15shvQY!>x(nnRK)U&ESujr)OUEC?DI!nq z=yX45W7L3TnO-dNMe^OUB;b>Ivd8$j$$(W%@5Z<8gVVnX^KjSU>z6U)Np!FKs~6 zW%>u=|K!u%7s~+@r0(*6X#=Xt^kwtiT>yYD0|46{D|a z;Uc}{{=4_%>AF%Qr6{jmNwcI1T@9rQs%f=_sFbE{X%*Sk`Cx^)1(;|;P21!ooBG(* zuq(V4&eID|;WTiN)s|gb8aRedn_L-LQ`mq-+S00m*#hp5fFV?Ea%H;z3mLF%nZ78v z{^4ekm{vDI_x7KU^YF$*>ZOw>7nL>IK}7Zt;O7ff4;<8eOg(I<(`(N7wb;|T$ z0F1n{hYdU3uyQR=r%kR%`CrR`sxm#crJ2fisZFIVus#@I|6P}|aV-C1jt?4W88A>R zu6k{0x@?#7F^?E43O!@?4}2?88gSnMAIZi|m+574155QL<&jRCoQ|yVG)^#{@2VJ0 z;$fQ3F=0p#^Itv_)9w@uqs)`V%v0sbWE93SJy~hy@N&PM_|+o*$Eo;Fh@in{R5e{{ zK-EKlreuo?kZp1bStFgos)qn=m+9+7RsIjVp){c6dZ6;R3vk`wa1GxU5j~vWCYM`{ z*=GWBc)GAg@T^G7|I4RGGgDYqrhmrd%9@M;MR4dti-c@@UDklarp|LmMC#SkV;KXc zn>x&`pI34Llx-pS%csXP21LE%c`zhfBc2&(3+D52Udl>lBCh}RoGo1Z)wq_HmX?;5 dmX?-g`5%ct!NaxS%V7Wj002ovPDHLkV1hA${MG;f literal 0 HcmV?d00001