From e881424beb928397b05861ea0ca3a11c8f5c8f1c Mon Sep 17 00:00:00 2001 From: Tom Ross Date: Tue, 27 Jun 2023 09:13:57 +0100 Subject: [PATCH] Show Cody walkthrough help text (#54175) --- client/cody-shared/src/chat/markdown.ts | 10 ++++++- client/cody-ui/src/Chat.tsx | 27 ++++++++++++------- client/cody-web/src/Chat.tsx | 2 +- client/cody/CHANGELOG.md | 1 + client/cody/src/chat/ChatViewProvider.ts | 1 + client/cody/src/main.ts | 12 ++++++++- client/cody/webviews/Chat.tsx | 1 + .../web/src/cody/components/ChatUI/ChatUi.tsx | 2 +- 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/client/cody-shared/src/chat/markdown.ts b/client/cody-shared/src/chat/markdown.ts index dceedb57079..60d3f021ce2 100644 --- a/client/cody-shared/src/chat/markdown.ts +++ b/client/cody-shared/src/chat/markdown.ts @@ -2,6 +2,14 @@ import { marked } from 'marked' import { registerHighlightContributions, renderMarkdown as renderMarkdownCommon } from '@sourcegraph/common' +/** + * Supported URIs to render as links in outputted markdown. + * - https?: Web + * - vscode: VS Code URL scheme (open in editor) + * - command:cody.welcome: VS Code command scheme exception we add to support directly linking to the welcome guide from within the chat. + */ +const ALLOWED_URI_REGEXP = /^((https?|vscode):\/\/[^\s#$./?].\S*|command:cody.welcome)$/i + const DOMPURIFY_CONFIG = { ALLOWED_TAGS: [ 'p', @@ -35,7 +43,7 @@ const DOMPURIFY_CONFIG = { 's', 'u', ], - ALLOWED_URI_REGEXP: /^(https?|vscode):\/\/[^\s#$./?].\S*$/i, + ALLOWED_URI_REGEXP, } /** diff --git a/client/cody-ui/src/Chat.tsx b/client/cody-ui/src/Chat.tsx index c4e304f6a2a..f09591e55d6 100644 --- a/client/cody-ui/src/Chat.tsx +++ b/client/cody-ui/src/Chat.tsx @@ -30,7 +30,8 @@ interface ChatProps extends ChatClassNames { submitButtonComponent: React.FunctionComponent suggestionButtonComponent?: React.FunctionComponent fileLinkComponent: React.FunctionComponent - afterTips?: string + helpMarkdown?: string + afterMarkdown?: string className?: string EditButtonContainer?: React.FunctionComponent editButtonOnSubmit?: (text: string) => void @@ -110,7 +111,8 @@ export const Chat: React.FunctionComponent = ({ submitButtonComponent: SubmitButton, suggestionButtonComponent: SuggestionButton, fileLinkComponent, - afterTips, + helpMarkdown, + afterMarkdown, className, codeBlocksCopyButtonClassName, codeBlocksInsertButtonClassName, @@ -227,11 +229,11 @@ export const Chat: React.FunctionComponent = ({ () => [ { speaker: 'assistant', - displayText: welcomeText(afterTips), + displayText: welcomeText({ helpMarkdown, afterMarkdown }), }, ...transcript, ], - [afterTips, transcript] + [helpMarkdown, afterMarkdown, transcript] ) return ( @@ -317,11 +319,18 @@ export const Chat: React.FunctionComponent = ({ ) } -function welcomeText(afterTips?: string): string { - return [ - "Hello! I'm Cody. I can write code and answer questions for you. See [Cody documentation](https://docs.sourcegraph.com/cody) for help and tips.", - afterTips, - ] +interface WelcomeTextOptions { + /** Provide users with a way to quickly access Cody docs/help.*/ + helpMarkdown?: string + /** Provide additional content to supplement the original message. Example: tips, privacy policy. */ + afterMarkdown?: string +} + +function welcomeText({ + helpMarkdown = 'See [Cody documentation](https://docs.sourcegraph.com/cody) for help and tips.', + afterMarkdown, +}: WelcomeTextOptions): string { + return ["Hello! I'm Cody. I can write code and answer questions for you. " + helpMarkdown, afterMarkdown] .filter(isDefined) .join('\n\n') } diff --git a/client/cody-web/src/Chat.tsx b/client/cody-web/src/Chat.tsx index 627efc1b265..428099bf5dd 100644 --- a/client/cody-web/src/Chat.tsx +++ b/client/cody-web/src/Chat.tsx @@ -42,7 +42,7 @@ export const Chat: React.FunctionComponent< textAreaComponent={TextArea} submitButtonComponent={SubmitButton} fileLinkComponent={FileLink} - afterTips={CODY_TERMS_MARKDOWN} + afterMarkdown={CODY_TERMS_MARKDOWN} transcriptItemClassName={styles.transcriptItem} humanTranscriptItemClassName={styles.humanTranscriptItem} transcriptItemParticipantClassName={styles.transcriptItemParticipant} diff --git a/client/cody/CHANGELOG.md b/client/cody/CHANGELOG.md index cc5dd78245f..065010b6208 100644 --- a/client/cody/CHANGELOG.md +++ b/client/cody/CHANGELOG.md @@ -37,6 +37,7 @@ Starting from `0.2.0`, Cody is using `major.EVEN_NUMBER.patch` for release versi - New sign-in and sign-out flow. [pull/53434](https://github.com/sourcegraph/sourcegraph/pull/53434) - Analytical logs are now displayed in the Output view. [pull/53870](https://github.com/sourcegraph/sourcegraph/pull/53870) - Renamed Inline Assist to Inline Chat. [pull/53725](https://github.com/sourcegraph/sourcegraph/pull/53725) +- Chat: Link to the "Getting Started" guide directly from the first chat message instead of the external documentation website. [pull/54175](https://github.com/sourcegraph/sourcegraph/pull/54175) ## [0.2.5] diff --git a/client/cody/src/chat/ChatViewProvider.ts b/client/cody/src/chat/ChatViewProvider.ts index cef35fae517..a374cd3ef3d 100644 --- a/client/cody/src/chat/ChatViewProvider.ts +++ b/client/cody/src/chat/ChatViewProvider.ts @@ -833,6 +833,7 @@ export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disp webviewView.webview.options = { enableScripts: true, localResourceRoots: [webviewPath], + enableCommandUris: true, } // Create Webview using client/cody/index.html diff --git a/client/cody/src/main.ts b/client/cody/src/main.ts index 9452e165694..d1890c5d9c3 100644 --- a/client/cody/src/main.ts +++ b/client/cody/src/main.ts @@ -242,7 +242,17 @@ const register = async ( vscode.commands.registerCommand('cody.feedback', () => vscode.env.openExternal(vscode.Uri.parse(CODY_FEEDBACK_URL.href)) ), - vscode.commands.registerCommand('cody.welcome', () => + vscode.commands.registerCommand('cody.welcome', async () => { + // Hack: We have to run this twice to force VS Code to register the walkthrough + // Open issue: https://github.com/microsoft/vscode/issues/186165 + await vscode.commands.executeCommand('workbench.action.openWalkthrough') + return vscode.commands.executeCommand( + 'workbench.action.openWalkthrough', + 'sourcegraph.cody-ai#welcome', + false + ) + }), + vscode.commands.registerCommand('cody.welcome-mock', () => vscode.commands.executeCommand('workbench.action.openWalkthrough', 'sourcegraph.cody-ai#welcome', false) ), vscode.commands.registerCommand('cody.walkthrough.showLogin', () => diff --git a/client/cody/webviews/Chat.tsx b/client/cody/webviews/Chat.tsx index 06274b32670..c02dc30f6e5 100644 --- a/client/cody/webviews/Chat.tsx +++ b/client/cody/webviews/Chat.tsx @@ -128,6 +128,7 @@ export const Chat: React.FunctionComponent // down here to render cody is disabled on the instance nicely. isCodyEnabled={true} codyNotEnabledNotice={undefined} + helpMarkdown="See [Getting Started](command:cody.welcome) for help and tips." /> ) } diff --git a/client/web/src/cody/components/ChatUI/ChatUi.tsx b/client/web/src/cody/components/ChatUI/ChatUi.tsx index ad082760444..b2dfb86585b 100644 --- a/client/web/src/cody/components/ChatUI/ChatUi.tsx +++ b/client/web/src/cody/components/ChatUI/ChatUi.tsx @@ -116,7 +116,7 @@ export const ChatUI: React.FC = ({ codyChatStore, isSourcegraphApp submitButtonComponent={SubmitButton} fileLinkComponent={isSourcegraphApp ? AppFileLink : FileLink} className={styles.container} - afterTips={transcriptHistory.length > 1 ? '' : CODY_TERMS_MARKDOWN} + afterMarkdown={transcriptHistory.length > 1 ? '' : CODY_TERMS_MARKDOWN} transcriptItemClassName={styles.transcriptItem} humanTranscriptItemClassName={styles.humanTranscriptItem} transcriptItemParticipantClassName="text-muted"