diff --git a/ci/build/build-vscode.sh b/ci/build/build-vscode.sh index 871a801aa30f..68afbe2e5929 100755 --- a/ci/build/build-vscode.sh +++ b/ci/build/build-vscode.sh @@ -72,9 +72,9 @@ main() { "enableTelemetry": true, "quality": "stable", "codeServerVersion": "$VERSION", - "nameShort": "code-server", - "nameLong": "code-server", - "applicationName": "code-server", + "nameShort": "Code", + "nameLong": "Visual Studio Code", + "applicationName": "code", "dataFolderName": ".code-server", "win32MutexName": "codeserver", "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE", @@ -136,7 +136,7 @@ EOF fix-bin-script helpers/browser.cmd ;; *) - fix-bin-script remote-cli/code-server + fix-bin-script remote-cli/code fix-bin-script helpers/browser.sh ;; esac diff --git a/ci/build/code-server-nfpm.sh b/ci/build/code-server-nfpm.sh index e12f493ba92c..92a2a9ccdb1d 100755 --- a/ci/build/code-server-nfpm.sh +++ b/ci/build/code-server-nfpm.sh @@ -1,3 +1,3 @@ #!/usr/bin/env sh -exec /usr/lib/code-server/bin/code-server "$@" +exec /usr/lib/vscode/lib/vscode/bin/remote-cli/code "$@" diff --git a/ci/build/generate-my-patch.sh b/ci/build/generate-my-patch.sh new file mode 100755 index 000000000000..1fd1ea2858d9 --- /dev/null +++ b/ci/build/generate-my-patch.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# Generate patches/my-app-change.diff +# +# Run this whenever upstream code-server or VS Code version changes. +# It applies all upstream patches, injects the custom remote indicator code, +# then generates a fresh diff with correct line numbers. +# +# Usage: ./ci/build/generate-my-patch.sh + +set -euo pipefail + +cd "$(dirname "${0}")/../.." + +PATCH_NAME="my-app-change" +PATCH_FILE="patches/${PATCH_NAME}.diff" +TARGET="lib/vscode/src/vs/server/node/webClientServer.ts" + +echo "=== Cleaning submodule ===" +cd lib/vscode +git checkout -- . 2>/dev/null || true +git clean -fdx 2>/dev/null || true +cd ../.. + +# Reset quilt state completely +quilt pop -af 2>/dev/null || true + +echo "=== Applying patches up to (but not including) $PATCH_NAME ===" +while IFS= read -r patch; do + [[ -z "$patch" || "$patch" == \#* ]] && continue + if [ "$patch" = "${PATCH_NAME}.diff" ]; then + break + fi + quilt push 2>&1 || { echo "FAILED at $patch"; exit 1; } +done < patches/series + +echo "=== Verifying target file ===" +if ! grep -q 'callbackRoute: callbackRoute$' "$TARGET"; then + echo "ERROR: Cannot find 'callbackRoute: callbackRoute' in $TARGET" + echo "The target pattern may have changed. Please update this script." + exit 1 +fi + +echo "=== Committing upstream patched state ===" +cd lib/vscode +git add -A +git commit -m "upstream-patches" --allow-empty 2>/dev/null || true +cd ../.. + +echo "=== Injecting remote indicator code ===" +python3 -c " +import sys +with open('$TARGET', 'r') as f: + content = f.read() + +old = ' callbackRoute: callbackRoute\n' +new = ''' callbackRoute: callbackRoute, + windowIndicator: process.env.MY_APP_CS_REMOTE_NAME ? { + label: \`\$(remote) \${process.env.MY_APP_CS_REMOTE_NAME}\`, + tooltip: process.env.MY_APP_CS_REMOTE_NAME + } : undefined, +''' + +if old not in content: + print('ERROR: Cannot find callbackRoute pattern') + sys.exit(1) + +content = content.replace(old, new, 1) +with open('$TARGET', 'w') as f: + f.write(content) +print('Injected successfully') +" + +echo "=== Generating diff against upstream state ===" +( cd lib/vscode && git diff HEAD -- src/vs/server/node/webClientServer.ts ) > /tmp/my-app-change-raw.diff + +echo "=== Cleaning up (reverting temp commit) ===" +cd lib/vscode +git reset HEAD~1 2>/dev/null || true +git checkout -- . 2>/dev/null || true +git clean -fdx 2>/dev/null || true +cd ../.. + +echo "=== Unapplying quilt patches ===" +quilt pop -af 2>/dev/null || true + +echo "=== Writing patch file ===" +{ + echo "Support MY_APP_CS_REMOTE_NAME environment variable for remote indicator" + echo "" + echo "If MY_APP_CS_REMOTE_NAME is set, the bottom-left status bar will show a" + echo "remote indicator with the provided name instead of the default \"Web\" label." + echo "" + echo "# Auto-generated by ci/build/generate-my-patch.sh" + echo "# Re-run after any upstream update to regenerate correct line numbers." + echo "" + echo "Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts" + echo "===================================================================" + echo "--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts" + echo "+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts" + tail -n +5 /tmp/my-app-change-raw.diff +} > "$PATCH_FILE" + +rm -f /tmp/my-app-change-raw.diff + +echo "" +echo "=== Done: $PATCH_FILE generated ===" diff --git a/ci/build/nfpm.yaml b/ci/build/nfpm.yaml index 4b0ee371a2eb..6f718524b884 100644 --- a/ci/build/nfpm.yaml +++ b/ci/build/nfpm.yaml @@ -1,4 +1,4 @@ -name: "code-server" +name: "vscode" arch: "${NFPM_ARCH}" platform: "linux" version: "v${VERSION}" @@ -13,7 +13,7 @@ license: "MIT" contents: - src: ./ci/build/code-server-nfpm.sh - dst: /usr/bin/code-server + dst: /usr/bin/code - src: ./ci/build/code-server@.service dst: /usr/lib/systemd/system/code-server@.service @@ -22,4 +22,4 @@ contents: dst: /usr/lib/systemd/user/code-server.service - src: ./release/* - dst: /usr/lib/code-server + dst: /usr/lib/vscode diff --git a/lib/vscode b/lib/vscode index 93cfdd489c3b..6928394f91b6 160000 --- a/lib/vscode +++ b/lib/vscode @@ -1 +1 @@ -Subproject commit 93cfdd489c3b228840d0f86ec77c3636277c93ea +Subproject commit 6928394f91b684055b873eecb8bc281365131f1c diff --git a/patches/integration.diff b/patches/integration.diff index a9244dd1734a..dd4240c06b9f 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -23,16 +23,16 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts +import { serverOptions, ServerParsedArgs } from './serverEnvironmentService.js'; import product from '../../platform/product/common/product.js'; import * as perf from '../../base/common/performance.js'; - + @@ -34,38 +34,47 @@ const errorReporter: ErrorReporter = { } }; - + -const args = parseArgs(process.argv.slice(2), serverOptions, errorReporter); +function parse(): ServerParsedArgs { + return parseArgs(process.argv.slice(2), serverOptions, errorReporter); +} - + -const REMOTE_DATA_FOLDER = args['server-data-dir'] || process.env['VSCODE_AGENT_FOLDER'] || join(os.homedir(), product.serverDataFolderName || '.vscode-remote'); -const USER_DATA_PATH = join(REMOTE_DATA_FOLDER, 'data'); -const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User'); @@ -74,7 +74,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts + }); + return REMOTE_DATA_FOLDER; +} - + /** * invoked by server-main.js */ @@ -83,7 +83,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts +function spawnCli(args = parse()): Promise { + return runCli(args, createDirs(args), serverOptions); } - + /** * invoked by server-main.js */ @@ -175,20 +175,20 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts @@ -140,6 +141,9 @@ export class BrowserMain extends Disposa // Startup const instantiationService = workbench.startup(); - + + const codeServerClient = this._register(instantiationService.createInstance(CodeServerClient)); + await codeServerClient.startup(); + // Window this._register(instantiationService.createInstance(BrowserWindow)); - + Index: code-server/lib/vscode/src/vs/base/common/product.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/product.ts +++ code-server/lib/vscode/src/vs/base/common/product.ts -@@ -84,6 +84,8 @@ export interface IAgentSdkProductConfig - } - +@@ -65,6 +65,8 @@ export type ExtensionVirtualWorkspaceSup + }; + export interface IProductConfiguration { + readonly codeServerVersion?: string + @@ -206,12 +206,12 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html - + + - + @@ -26,8 +27,9 @@ - + - - @@ -219,7 +219,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html + + - + Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html =================================================================== @@ -232,12 +232,12 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html - + + - + @@ -23,8 +24,9 @@ - + - - @@ -245,7 +245,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html + + - + Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== @@ -253,7 +253,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts @@ -353,6 +353,7 @@ export class WebClientServer { } : undefined; - + const productConfiguration: Partial> = { + codeServerVersion: this._productService.codeServerVersion, embedderIdentifier: 'server-distro', @@ -266,7 +266,7 @@ Index: code-server/lib/vscode/src/server-main.ts @@ -22,6 +22,9 @@ import { IServerAPI } from './vs/server/ perf.mark('code/server/start'); (globalThis as { vscodeServerStartTime?: number }).vscodeServerStartTime = performance.now(); - + +// This is not indented to make the diff less noisy. We need to move this out +// of the top-level so it will not run immediately and we can control the start. +async function start() { @@ -278,7 +278,7 @@ Index: code-server/lib/vscode/src/server-main.ts }); } +} - + function sanitizeStringArg(val: unknown): string | undefined { if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array @@ -283,3 +287,22 @@ function prompt(question: string): Promi @@ -304,21 +304,3 @@ Index: code-server/lib/vscode/src/server-main.ts +if (!process.env.CODE_SERVER_PARENT_PID) { + start(); +} -Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts -+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialog.ts -@@ -47,8 +47,11 @@ export function createWorkbenchDialogOpt - - export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } { - const detailString = (useAgo: boolean): string => { -- return localize('aboutDetail', -- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", -+ return localize('aboutCodeServerDetail', -+ "code-server: {0}", -+ productService.codeServerVersion ? `v${productService.codeServerVersion}` : 'Unknown' -+ ) + '\n' + localize('aboutDetail', -+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", - productService.version || 'Unknown', - productService.commit || 'Unknown', - productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown', diff --git a/patches/logout.diff b/patches/logout.diff index 5af694506d6c..6ed51c16e039 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -13,7 +13,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts readonly rootEndpoint?: string readonly updateEndpoint?: string + readonly logoutEndpoint?: string - + readonly version: string; readonly date?: string; Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts @@ -25,17 +25,17 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts /* ----- code-server ----- */ 'disable-update-check': { type: 'boolean' }, + 'auth': { type: 'string' }, - + /* ----- server setup ----- */ - + @@ -112,6 +113,7 @@ export const serverOptions: OptionDescri export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; + 'auth'?: string; - + /* ----- server setup ----- */ - + Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts @@ -61,7 +61,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts import { INotificationService, Severity } from '../../platform/notification/common/notification.js'; import { IProductService } from '../../platform/product/common/productService.js'; import { IStorageService, StorageScope, StorageTarget } from '../../platform/storage/common/storage.js'; - + export class CodeServerClient extends Disposable { + static LOGOUT_COMMAND_ID = 'code-server.logout'; + @@ -77,10 +77,10 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts + this.addLogoutCommand(this.productService.logoutEndpoint); + } } - + private checkUpdates(updateEndpoint: string) { @@ -132,4 +140,25 @@ export class CodeServerClient extends Di - + updateLoop(); } + @@ -99,7 +99,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts + MenuRegistry.appendMenuItem(menuId, { + command: { + id: CodeServerClient.LOGOUT_COMMAND_ID, -+ title: localize('logout', "Sign out of {0}", 'code-server'), ++ title: localize('logout', "退出", 'code-server'), + }, + }); + } diff --git a/patches/my-app-change.diff b/patches/my-app-change.diff new file mode 100644 index 000000000000..ea1b0a3ae3f9 --- /dev/null +++ b/patches/my-app-change.diff @@ -0,0 +1,25 @@ +Support MY_APP_CS_REMOTE_NAME environment variable for remote indicator + +If MY_APP_CS_REMOTE_NAME is set, the bottom-left status bar will show a +remote indicator with the provided name instead of the default "Web" label. + +# Auto-generated by ci/build/generate-my-patch.sh +# Re-run after any upstream update to regenerate correct line numbers. + +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 +@@ -414,7 +414,11 @@ export class WebClientServer { + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), + productConfiguration, +- callbackRoute: callbackRoute ++ callbackRoute: callbackRoute, ++ windowIndicator: process.env.MY_APP_CS_REMOTE_NAME ? { ++ label: `$(remote) ${process.env.MY_APP_CS_REMOTE_NAME}`, ++ tooltip: process.env.MY_APP_CS_REMOTE_NAME ++ } : undefined, + }; + + const cookies = cookie.parse(req.headers.cookie || ''); diff --git a/patches/series b/patches/series index 6f438da313bf..1601f8e158b2 100644 --- a/patches/series +++ b/patches/series @@ -24,3 +24,4 @@ trusted-domains.diff signature-verification.diff copilot.diff app-name.diff +my-app-change.diff diff --git a/src/node/constants.ts b/src/node/constants.ts index bb6873dfa113..57c42bbeafcf 100644 --- a/src/node/constants.ts +++ b/src/node/constants.ts @@ -32,7 +32,7 @@ export const httpProxyUri = * for outputting to the console. */ export function getVersionString(): string { - return [version, commit, "with Code", codeVersion].join(" ") + return [codeVersion].join(" ") } /** diff --git a/src/node/entry.ts b/src/node/entry.ts index 749b6e966cbc..634aae235c55 100644 --- a/src/node/entry.ts +++ b/src/node/entry.ts @@ -24,7 +24,7 @@ async function entry(): Promise { const args = await setDefaults(cliArgs, configArgs) if (args.help) { - console.log("code-server", getVersionString()) + console.log("Visual Studio Code", getVersionString()) console.log("") console.log(`Usage: code-server [options] [path]`) console.log(` - Opening a directory: code-server ./path/to/your/project`)