Skip to content

Commit

Permalink
Merge pull request #182 from open-sauced/beta
Browse files Browse the repository at this point in the history
v1.7.0-beta.2 -> main
  • Loading branch information
bdougie authored Jun 15, 2023
2 parents 5fd2e50 + d1a400b commit facf077
Show file tree
Hide file tree
Showing 22 changed files with 407 additions and 214 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@

> All notable changes to this project will be documented in this file
## [1.7.0-beta.2](https://github.com/open-sauced/ai/compare/v1.7.0-beta.1...v1.7.0-beta.2) (2023-06-15)


### 🍕 Features

* AI PR review menu ([#174](https://github.com/open-sauced/ai/issues/174)) ([ef52439](https://github.com/open-sauced/ai/commit/ef5243921ced600cec4ed0270c76ecdf9885ab0b))

## [1.7.0-beta.1](https://github.com/open-sauced/ai/compare/v1.6.1-beta.1...v1.7.0-beta.1) (2023-06-14)


### 🍕 Features

* Added Contributed Repos to profile page ([#181](https://github.com/open-sauced/ai/issues/181)) ([4901f7b](https://github.com/open-sauced/ai/commit/4901f7b322b87e27ed755be598c2975d6329f067))

## [1.6.1-beta.1](https://github.com/open-sauced/ai/compare/v1.6.0...v1.6.1-beta.1) (2023-06-13)


### 🐛 Bug Fixes

* update email invite message ([c1008e5](https://github.com/open-sauced/ai/commit/c1008e5f94f82cc87f9f3691bdd8d664b6a6f684))

## [1.6.0](https://github.com/open-sauced/ai/compare/v1.5.0...v1.6.0) (2023-06-13)


Expand Down
11 changes: 5 additions & 6 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "opensauced-browser-extension",
"private": true,
"version": "1.6.0",
"version": "1.7.0-beta.2",
"files": [
"dist"
],
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export const OPEN_SAUCED_USER_INSIGHTS_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/u
export const OPEN_SAUCED_AI_PR_DESCRIPTION_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/prs/description/generate`;
export const OPEN_SAUCED_USER_HIGHLIGHTS_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/user/highlights`;
export const OPEN_SAUCED_AI_CODE_REFACTOR_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/prs/suggestion/generate`;
export const OPEN_SAUCED_AI_CODE_EXPLANATION_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/prs/explanation/generate`;
export const OPEN_SAUCED_AI_CODE_TEST_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/prs/test/generate`;
export const OPEN_SAUCED_HIGHLIGHTS_ENDPOINT = `${OPEN_SAUCED_API_ENDPOINT}/highlights/list`;

// GitHub constants/selectors
Expand Down

This file was deleted.

49 changes: 49 additions & 0 deletions src/content-scripts/components/AICodeReview/AICodeReviewButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { createHtmlElement } from "../../../utils/createHtmlElement";
import openSaucedLogoIcon from "../../../assets/opensauced-icon.svg";
import { generateCodeExplanation, generateCodeSuggestion, generateCodeTest } from "../../../utils/ai-utils/openai";
import {
AICodeReviewMenu,
AICodeReviewMenuItem,
} from "./AICodeReviewMenu";


export const AICodeReviewButton = (commentNode: HTMLElement) => {
const changeSuggestorButton = createHtmlElement("a", {
innerHTML: `<span id="ai-change-gen" class="toolbar-item btn-octicon">
<img class="octicon octicon-heading" height="16px" width="16px" id="ai-description-button-logo" src=${chrome.runtime.getURL(
openSaucedLogoIcon,
)}>
</span>`,
onclick: (event: MouseEvent) => {
event.stopPropagation();
menu.classList.toggle("hidden");
},
id: "os-ai-change-gen",
});

const refactorCode = AICodeReviewMenuItem(
"Refactor Code",
"Generate a code refactor",
generateCodeSuggestion,
commentNode,
);
const testCode = AICodeReviewMenuItem(
"Test Code",
"Generate a test for the code",
generateCodeTest,
commentNode,
);
const explainCode = AICodeReviewMenuItem(
"Explain Code",
"Generate an explanation for the code",
generateCodeExplanation,
commentNode,
);

const menu = AICodeReviewMenu([refactorCode, testCode, explainCode]);

changeSuggestorButton.append(menu);
return changeSuggestorButton;
};


148 changes: 148 additions & 0 deletions src/content-scripts/components/AICodeReview/AICodeReviewMenu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import {
SUPABASE_LOGIN_URL,
GITHUB_PR_SUGGESTION_TEXT_AREA_SELECTOR,
} from "../../../constants";
import { insertTextAtCursor } from "../../../utils/ai-utils/cursorPositionInsert";
import {
DescriptionConfig,
getAIDescriptionConfig,
} from "../../../utils/ai-utils/descriptionconfig";
import { getAuthToken, isLoggedIn } from "../../../utils/checkAuthentication";
import { createHtmlElement } from "../../../utils/createHtmlElement";
import { isOutOfContextBounds } from "../../../utils/fetchGithubAPIData";

type SuggestionGenerator = (
token: string,
code: string,
config: DescriptionConfig
) => Promise<string | undefined>;

export const AICodeReviewMenu = (items: HTMLLIElement[]) => {
const menu = createHtmlElement("div", {
className: "SelectMenu js-slash-command-menu hidden mt-6",
innerHTML: `<div class="SelectMenu-modal no-underline">
<header class="SelectMenu-header">
<div class="flex-1">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class="octicon octicon-code-square">
<path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
<span class="color-fg-muted text-small pl-1">OpenSauced.ai</span>
</div>
<div class="Label Label--success">AI</div>
<a class="ml-1 color-fg-muted d-block" target="_blank" href="https://github.com/orgs/open-sauced/discussions">
Give feedback
</a>
</header>
<div class="SelectMenu-list js-command-list-container" style="max-height: 270px;" id="combobox-5123">
<ul role="listbox" class="SelectMenu-list js-slash-command-menu-items">
</ul>
</div>
</div>`,
});

menu.querySelector("ul")?.append(...items);

document.addEventListener("click", event => {
if (event.target instanceof HTMLElement) {
menu.classList.add("hidden");
}
});
return menu;
};

export const AICodeReviewMenuItem = (title: string, description: string, suggestionGenerator: SuggestionGenerator, commentNode: HTMLElement) => {
const menuItem = createHtmlElement("li", {
className: "SelectMenu-item d-block slash-command-menu-item",
role: "option",
onclick: () => {
void handleSubmit(suggestionGenerator, commentNode);
},
innerHTML: `<h5>${title}</h5>
<span class="command-description">${description}</span>`,
});

return menuItem;
};

const handleSubmit = async (
suggestionGenerator: SuggestionGenerator,
commentNode: HTMLElement,
) => {
const logo = commentNode.querySelector("#ai-description-button-logo");
const button = commentNode.querySelector("#os-ai-change-gen");

try {
if (!(await isLoggedIn())) {
return window.open(SUPABASE_LOGIN_URL, "_blank");
}

if (!logo || !button) {
return;
}

const descriptionConfig = await getAIDescriptionConfig();

if (!descriptionConfig) {
return;
}

logo.classList.toggle("animate-spin");
button.classList.toggle("pointer-events-none");

const selectedLines = document.querySelectorAll(
".code-review.selected-line",
);
let selectedCode = Array.from(selectedLines)
.map(line => line.textContent)
.join("\n");

// find input with name="position" and get its value
if (!selectedCode) {
const positionElement = commentNode.querySelector(
"input[name=position]",
)!;
const position = positionElement.getAttribute("value")!;

const codeDiv = document.querySelector(`[data-line-number="${position}"]`)
?.nextSibling?.nextSibling as HTMLElement;

selectedCode =
codeDiv.getElementsByClassName("blob-code-inner")[0].textContent!;
}
if (
isOutOfContextBounds(
[selectedCode, [] ],
descriptionConfig.config.maxInputLength,
)
) {
logo.classList.toggle("animate-spin");
return alert(
`Max input length exceeded. Try reducing the number of selected lines to refactor.`,
);
}
const token = await getAuthToken();
const suggestionStream = await suggestionGenerator(
token,
selectedCode,
descriptionConfig,
);

logo.classList.toggle("animate-spin");
button.classList.toggle("pointer-events-none");
if (!suggestionStream) {
return console.error("No description was generated!");
}
const textArea = commentNode.querySelector(
GITHUB_PR_SUGGESTION_TEXT_AREA_SELECTOR,
)!;

insertTextAtCursor(textArea as HTMLTextAreaElement, suggestionStream);
} catch (error: unknown) {
logo?.classList.toggle("animate-spin");
button?.classList.toggle("pointer-events-none");

if (error instanceof Error) {
console.error("Description generation error:", error.message);
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { createHtmlElement } from "../../../utils/createHtmlElement";
import openSaucedLogoIcon from "../../../assets/opensauced-icon.svg";
import { getPullRequestAPIURL } from "../../../utils/urlMatchers";
import { getDescriptionContext, isOutOfContextBounds } from "../../../utils/fetchGithubAPIData";
import { generateDescription } from "../../../utils/aiprdescription/openai";
import { generateDescription } from "../../../utils/ai-utils/openai";
import { GITHUB_PR_COMMENT_TEXT_AREA_SELECTOR, SUPABASE_LOGIN_URL } from "../../../constants";
import { insertTextAtCursor } from "../../../utils/aiprdescription/cursorPositionInsert";
import { getAIDescriptionConfig } from "../../../utils/aiprdescription/descriptionconfig";
import { insertTextAtCursor } from "../../../utils/ai-utils/cursorPositionInsert";
import { getAIDescriptionConfig } from "../../../utils/ai-utils/descriptionconfig";
import { getAuthToken, isLoggedIn } from "../../../utils/checkAuthentication";

export const DescriptionGeneratorButton = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const InviteToOpenSaucedModal = (
) => {
const emailBody =
typeof emailAddress === "string" &&
`Hey ${username}. I'm using OpenSauced to keep track of my contributions and discover new projects. Check it out at https://opensauced.pizza/`;
`Hey ${username}. I'm using OpenSauced to keep track of my contributions and discover new projects. Try connecting your GitHub to https://opensauced.pizza/`;
const emailHref =
typeof emailAddress === "string" &&
`mailto:${emailAddress}?subject=${encodeURIComponent(
Expand Down
11 changes: 0 additions & 11 deletions src/hooks/useRefs.ts

This file was deleted.

Loading

0 comments on commit facf077

Please sign in to comment.