Modify Help: Getting Started

This modifies some text on the Getting Started page and adds text about using
code-server on a team.

It is enabled by default but can be overriden using the cli flag
`--disable-getting-started-override`.

Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
@@ -3,7 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import { $, Dimension, addDisposableListener, append, clearNode, reset } from '../../../../base/browser/dom.js';
+import { $, Dimension, addDisposableListener, append, clearNode, reset, prepend } from '../../../../base/browser/dom.js';
 import { renderFormattedText } from '../../../../base/browser/formattedTextRenderer.js';
 import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
 import { Button } from '../../../../base/browser/ui/button/button.js';
@@ -54,7 +54,7 @@ import { IRecentFolder, IRecentWorkspace
 import { OpenRecentAction } from '../../../browser/actions/windowActions.js';
 import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from '../../../browser/actions/workspaceActions.js';
 import { EditorPane } from '../../../browser/parts/editor/editorPane.js';
-import { WorkbenchStateContext } from '../../../common/contextkeys.js';
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from '../../../common/contextkeys.js';
 import { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js';
 import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js';
 import './gettingStartedColors.js';
@@ -872,6 +872,72 @@ export class GettingStartedPage extends
 			$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
 		);
 
+		let gettingStartedCoder: HTMLElement = $('.header', {});
+		if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+			gettingStartedCoder = $('.gettingStartedCategory', {},
+				$('h2', {
+					style: 'margin-bottom: 12px',
+				}, 'Next Up'),
+				$('a', {
+					href: 'https://cdr.co/code-server-to-coder',
+					target: '_blank',
+				},
+					$('button', {
+						style: [
+							'padding: 10px 16px	',
+							'border-radius: 4px',
+							'background: linear-gradient(94.04deg, #7934DA 0%, #4D52E0 101.2%)',
+							'color: white',
+							'overflow: hidden',
+							'margin-right: 14px',
+						].join(';'),
+					},
+					$('h3', {
+						style: [
+							'margin: 0px 0px 6px',
+							'font-weight: 500',
+						].join(';'),
+					}, 'Deploy code-server for your team'),
+					$('p', {
+						style: [
+							'margin: 0',
+							'font-size: 13px',
+							'color: #dcdee2',
+						].join(';'),
+					}, 'Provision software development environments on your infrastructure with Coder.'),
+					$('p', {
+						style: [
+							'margin-top: 8px',
+							'font-size: 13px',
+							'color: #dcdee2',
+						].join(';'),
+					}, 'Coder is a self-service portal which provisions via Terraform—Linux, macOS, Windows, x86, ARM, and, of course, Kubernetes based infrastructure.'),
+					$('p', {
+						style: [
+							'margin: 0',
+							'margin-top: 8px',
+							'font-size: 13px',
+							'display: flex',
+							'align-items: center',
+						].join(';'),
+					}, 'Get started ', $('span', {
+						class: ThemeIcon.asClassName(Codicon.arrowRight),
+						style: [
+							'color: white',
+							'margin-left: 8px',
+						].join(';'),
+					})),
+					$('img', {
+						src: './_static/src/browser/media/templates.png',
+						style: [
+							'margin-bottom: -65px',
+						].join(';'),
+					}),
+					),
+				),
+			);
+		}
+
 		const leftColumn = $('.categories-column.categories-column-left', {},);
 		const rightColumn = $('.categories-column.categories-column-right', {},);
 
@@ -907,6 +973,9 @@ export class GettingStartedPage extends
 				recentList.setLimit(5);
 				reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
 			}
+			if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+				prepend(rightColumn, gettingStartedCoder)
+			}
 		};
 
 		gettingStartedList.onDidChange(layoutLists);
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
@@ -60,6 +60,15 @@
 	display: block;
 }
 
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder {
+	margin-bottom: 0.2em;
+}
+
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder-coder {
+	font-size: 1em;
+	margin-top: 0.2em;
+}
+
 .monaco-workbench.hc-black .part.editor > .content .gettingStartedContainer .subtitle,
 .monaco-workbench.hc-light .part.editor > .content .gettingStartedContainer .subtitle {
 	font-weight: 200;
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -313,6 +313,11 @@ export interface IWorkbenchConstructionO
 	 */
 	readonly isEnabledFileUploads?: boolean
 
+	/**
+	 * Whether to use Coder's custom Getting Started text.
+	 */
+	readonly isEnabledCoderGettingStarted?: boolean
+
 	//#endregion
 
 	//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -44,6 +44,11 @@ export interface IBrowserWorkbenchEnviro
 	readonly isEnabledFileUploads?: boolean;
 
 	/**
+	 * Enable Coder's custom getting started text.
+	 */
+	readonly isEnabledCoderGettingStarted?: boolean;
+
+	/**
 	 * Gets whether a resolver extension is expected for the environment.
 	 */
 	readonly expectsResolverExtension: boolean;
@@ -135,6 +140,13 @@ export class BrowserWorkbenchEnvironment
 		return this.options.isEnabledFileUploads;
 	}
 
+	get isEnabledCoderGettingStarted(): boolean {
+		if (typeof this.options.isEnabledCoderGettingStarted === "undefined") {
+			throw new Error('isEnabledCoderGettingStarted was not provided to the browser');
+		}
+		return this.options.isEnabledCoderGettingStarted;
+	}
+
 	@memoize
 	get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
 
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -20,6 +20,7 @@ export const serverOptions: OptionDescri
 	'auth': { type: 'string' },
 	'disable-file-downloads': { type: 'boolean' },
 	'disable-file-uploads': { type: 'boolean' },
+	'disable-getting-started-override': { type: 'boolean' },
 
 	/* ----- server setup ----- */
 
@@ -108,6 +109,7 @@ export interface ServerParsedArgs {
 	'auth'?: string;
 	'disable-file-downloads'?: boolean;
 	'disable-file-uploads'?: boolean;
+	'disable-getting-started-override'?: boolean,
 
 	/* ----- server setup ----- */
 
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -373,6 +373,7 @@ export class WebClientServer {
 			userDataPath: this._environmentService.userDataPath,
 			isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
 			isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
+			isEnabledCoderGettingStarted: !this._environmentService.args['disable-getting-started-override'],
 			_wrapWebWorkerExtHostInIframe,
 			developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
 			settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,7 +7,7 @@ import { Event } from '../../base/common
 import { Disposable, DisposableStore, MutableDisposable } from '../../base/common/lifecycle.js';
 import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
 import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext, IsSimulationContext } from '../../platform/contextkey/common/contextkeys.js';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
 import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
 import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
 import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
@@ -211,6 +211,7 @@ export class WorkbenchContextKeysHandler
 		// code-server
 		IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
 		IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
+		IsEnabledCoderGettingStarted.bindTo(this.contextKeyService).set(this.environmentService.isEnabledCoderGettingStarted ?? true)
 
 		this.registerListeners();
 	}
Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -41,6 +41,7 @@ export const InAutomationContext = new R
 
 export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
 export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
+export const IsEnabledCoderGettingStarted = new RawContextKey<boolean>('isEnabledCoderGettingStarted', true, true);
 
 //#endregion
 
