Compare commits

..

4 Commits

Author SHA1 Message Date
Asher
72a1ca8b3b Download rpm artifacts 2024-02-08 11:32:19 -09:00
Asher
5d59312755 Add new images to default targets 2024-02-08 11:26:12 -09:00
Dmitry Sharshakov
a70a36f04c docker: add openSUSE Tumbleweed based image 2024-02-08 23:06:27 +03:00
Dmitry Sharshakov
828f94b6a2 docker: add Fedora 39 based image
Fixes #6661
2024-02-08 22:38:25 +03:00
62 changed files with 803 additions and 1251 deletions

View File

@@ -1,5 +1,6 @@
name: Bug report name: Bug report
description: File a bug report description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"] labels: ["bug", "triage"]
body: body:
- type: checkboxes - type: checkboxes
@@ -9,7 +10,6 @@ body:
options: options:
- label: I have searched the existing issues - label: I have searched the existing issues
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: OS/Web Information label: OS/Web Information
@@ -28,74 +28,55 @@ body:
- `code-server --version`: - `code-server --version`:
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Steps to Reproduce label: Steps to Reproduce
description: | description: |
Please describe exactly how to reproduce the bug. For example: 1. open code-server
1. Open code-server in Firefox 2. install extension
2. Install extension `foo.bar` from the extensions sidebar 3. run command
3. Run command `foo.bar.baz`
value: | value: |
1. 1.
2. 2.
3. 3.
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Expected label: Expected
description: What should happen? description: What should happen?
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Actual label: Actual
description: What actually happens? description: What actually happens?
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: logs id: logs
attributes: attributes:
label: Logs label: Logs
description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `yarn global add code-server`). description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `yarn global add code-server`).
render: shell
- type: textarea - type: textarea
attributes: attributes:
label: Screenshot/Video label: Screenshot/Video
description: Please include a screenshot, gif or screen recording of your issue. description: Please include a screenshot, gif or screen recording of your issue.
validations: validations:
required: false required: false
- type: checkboxes
- type: dropdown
attributes: attributes:
label: Does this bug reproduce in native VS Code? label: Does this issue happen in VS Code or GitHub Codespaces?
description: If the bug reproduces in native VS Code, submit the issue upstream instead (https://github.com/microsoft/vscode). description: Please try reproducing this issue in VS Code and GitHub Codespaces. If the bug reproduces in either VS Code or GitHub Codespaces, please submit the issue upstream instead (https://github.com/microsoft/vscode).
options: options:
- Yes, this is also broken in native VS Code - label: I tested this in native VS Code.
- No, this works as expected in native VS Code required: false
- This cannot be tested in native VS Code - label: This does not happen in native VS Code.
- I did not test native VS Code required: false
validations: - label: I tested this in GitHub Codespaces.
required: true required: false
- label: This does not happen in GitHub Codespaces.
- type: dropdown required: false
attributes:
label: Does this bug reproduce in GitHub Codespaces?
description: If the bug reproduces in GitHub Codespaces, submit the issue upstream instead (https://github.com/microsoft/vscode).
options:
- Yes, this is also broken in GitHub Codespaces
- No, this works as expected in GitHub Codespaces
- This cannot be tested in GitHub Codespaces
- I did not test GitHub Codespaces
validations:
required: true
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Are you accessing code-server over a secure context? label: Are you accessing code-server over a secure context?
@@ -103,7 +84,6 @@ body:
options: options:
- label: I am using a secure context. - label: I am using a secure context.
required: false required: false
- type: textarea - type: textarea
attributes: attributes:
label: Notes label: Notes

View File

@@ -1,7 +1,9 @@
--- ---
name: Documentation improvement name: Documentation improvement
about: Suggest a documentation improvement about: Suggest a documentation improvement
title: "[Docs]: "
labels: "docs" labels: "docs"
assignees: "@jsjoeio"
--- ---
## What is your suggestion? ## What is your suggestion?

View File

@@ -1,7 +1,9 @@
--- ---
name: Feature request name: Feature request
about: Suggest an idea to improve code-server about: Suggest an idea to improve code-server
title: "[Feat]: "
labels: enhancement labels: enhancement
assignees: ""
--- ---
## What is your suggestion? ## What is your suggestion?

View File

@@ -45,7 +45,7 @@ jobs:
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@v42
with: with:
files: | files: |
docs/** docs/**
@@ -76,14 +76,14 @@ jobs:
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@v42
with: with:
files: | files: |
ci/helm-chart/** ci/helm-chart/**
- name: Install helm - name: Install helm
if: steps.changed-files.outputs.any_changed == 'true' if: steps.changed-files.outputs.any_changed == 'true'
uses: azure/setup-helm@v4 uses: azure/setup-helm@v3.5
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@@ -107,7 +107,7 @@ jobs:
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@v42
with: with:
files: | files: |
**/*.ts **/*.ts
@@ -163,7 +163,7 @@ jobs:
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@v42
with: with:
files: | files: |
**/*.ts **/*.ts
@@ -206,7 +206,6 @@ jobs:
timeout-minutes: 60 timeout-minutes: 60
env: env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
DISABLE_V8_COMPILE_CACHE: 1
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -36,7 +36,7 @@ jobs:
cache: "yarn" cache: "yarn"
- name: Download npm package from release artifacts - name: Download npm package from release artifacts
uses: robinraju/release-downloader@v1.10 uses: robinraju/release-downloader@v1.9
with: with:
repository: "coder/code-server" repository: "coder/code-server"
tag: ${{ github.event.inputs.version || github.ref_name }} tag: ${{ github.event.inputs.version || github.ref_name }}
@@ -132,7 +132,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Validate package - name: Validate package
uses: heyhusen/archlinux-package-action@v2.2.1 uses: hapakaien/archlinux-package-action@v2
env: env:
VERSION: ${{ env.VERSION }} VERSION: ${{ env.VERSION }}
with: with:
@@ -184,7 +184,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Download deb artifacts - name: Download deb artifacts
uses: robinraju/release-downloader@v1.10 uses: robinraju/release-downloader@v1.9
with: with:
repository: "coder/code-server" repository: "coder/code-server"
tag: v${{ env.VERSION }} tag: v${{ env.VERSION }}
@@ -192,7 +192,7 @@ jobs:
out-file-path: "release-packages" out-file-path: "release-packages"
- name: Download rpm artifacts - name: Download rpm artifacts
uses: robinraju/release-downloader@v1.10 uses: robinraju/release-downloader@v1.9
with: with:
repository: "coder/code-server" repository: "coder/code-server"
tag: v${{ env.VERSION }} tag: v${{ env.VERSION }}

View File

@@ -81,7 +81,6 @@ jobs:
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
if: success() if: success()
continue-on-error: true
# NOTE@jsjoeio - we do this so we can strip out the v # NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1 # i.e. v4.9.1 -> 4.9.1
@@ -95,7 +94,7 @@ jobs:
VERSION: ${{ env.VERSION }} VERSION: ${{ env.VERSION }}
run: yarn package run: yarn package
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v1
with: with:
draft: true draft: true
discussion_category_name: "📣 Announcements" discussion_category_name: "📣 Announcements"
@@ -191,7 +190,7 @@ jobs:
VERSION: ${{ env.VERSION }} VERSION: ${{ env.VERSION }}
run: npm run package ${npm_config_arch} run: npm run package ${npm_config_arch}
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v1
with: with:
draft: true draft: true
discussion_category_name: "📣 Announcements" discussion_category_name: "📣 Announcements"
@@ -222,7 +221,7 @@ jobs:
# next update Node we can probably remove this. For now, install # next update Node we can probably remove this. For now, install
# setuptools since it contains distutils. # setuptools since it contains distutils.
- name: Install Python utilities - name: Install Python utilities
run: brew install python-setuptools run: python3 -m pip install setuptools
- name: Download npm package - name: Download npm package
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -253,7 +252,7 @@ jobs:
VERSION: ${{ env.VERSION }} VERSION: ${{ env.VERSION }}
run: yarn package run: yarn package
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v1
with: with:
draft: true draft: true
discussion_category_name: "📣 Announcements" discussion_category_name: "📣 Announcements"
@@ -270,7 +269,7 @@ jobs:
with: with:
name: npm-release-package name: npm-release-package
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v1
with: with:
draft: true draft: true
discussion_category_name: "📣 Announcements" discussion_category_name: "📣 Announcements"

View File

@@ -55,7 +55,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode - name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@fd25fed6972e341ff0007ddb61f77e88103953c2 uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
with: with:
scan-type: "fs" scan-type: "fs"
scan-ref: "." scan-ref: "."

View File

@@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in image mode - name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@fd25fed6972e341ff0007ddb61f77e88103953c2 uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
with: with:
image-ref: "docker.io/codercom/code-server:latest" image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true ignore-unfixed: true

View File

@@ -1 +1 @@
20.11.1 18.17.1

View File

@@ -22,128 +22,23 @@ Code v99.99.999
## Unreleased ## Unreleased
Code v1.90.0 ## [4.21.0](https://github.com/coder/code-server/releases/tag/v4.21.0) - 2021-02-05
### Fixed
- Cache a call to get CPU information used in telemetry that could result in a
lack responsiveness if it was particularly slow.
## [4.90.0](https://github.com/coder/code-server/releases/tag/v4.90.0) - 2024-06-11
Code v1.90.0
### Changed
- Updated to Code 1.90.0.
- Updated Node to 20.11.1.
### Added
- Send contents to the clipboard in the integrated terminal by piping to
`code-server --stdin-to-clipboard` or `code-server -c`.
You may want to make this an alias:
```
alias xclip="code-server --stdin-to-clipboard"
echo -n "hello world" | xclip
```
## [4.89.1](https://github.com/coder/code-server/releases/tag/v4.89.1) - 2024-04-14
Code v1.89.1
### Changed
- Updated to Code 1.89.1.
## [4.89.0](https://github.com/coder/code-server/releases/tag/v4.89.0) - 2024-04-08
Code v1.89.0
### Changed
- Updated to Code 1.89.0.
## [4.23.1](https://github.com/coder/code-server/releases/tag/v4.23.1) - 2024-04-15
Code v1.88.1
### Changed
- Updated to Code 1.88.1.
## [4.23.0](https://github.com/coder/code-server/releases/tag/v4.23.0) - 2024-04-08
Code v1.88.0
### Changed
- Updated to Code 1.88.0.
- Updated Node to 18.18.2.
### Fixed
- Fix masking the exit code when failing to install extensions on the command
line outside the integrated terminal. Installing extensions inside the
integrated terminal still masks the exit code and is an upstream bug.
## [4.22.1](https://github.com/coder/code-server/releases/tag/v4.22.1) - 2024-03-14
Code v1.87.2
### Changed
- Updated to Code 1.87.2.
- Enable keep-alive for proxy agent.
## [4.22.0](https://github.com/coder/code-server/releases/tag/v4.22.0) - 2024-03-03
Code v1.87.0
### Changed
- Updated to Code 1.87.0.
## [4.21.2](https://github.com/coder/code-server/releases/tag/v4.21.2) - 2024-02-28
Code v1.86.2
### Changed
- Updated to Code 1.86.2.
## [4.21.1](https://github.com/coder/code-server/releases/tag/v4.21.1) - 2024-02-09
Code v1.86.1
### Changed
- Updated to Code 1.86.1.
- Updated to Node 18.17.1.
### Added
- Docker images for Fedora and openSUSE.
## [4.21.0](https://github.com/coder/code-server/releases/tag/v4.21.0) - 2024-02-05
Code v1.86.0 Code v1.86.0
### Changed ## Changed
- Updated to Code 1.86.0. - Updated to Code 1.86.0
## [4.20.1](https://github.com/coder/code-server/releases/tag/v4.20.1) - 2024-01-22 ## [4.20.1](https://github.com/coder/code-server/releases/tag/v4.20.1) - 2021-01-22
Code v1.85.2 Code v1.85.2
### Changed ## Changed
- Updated to Code 1.85.2. - Updated to Code 1.85.2.
### Fixed ## Fixed
- Query variables are no longer double-encoded when going over the path proxy. - Query variables are no longer double-encoded when going over the path proxy.

View File

@@ -51,18 +51,6 @@ symlink_bin_script() {
cd "$oldpwd" cd "$oldpwd"
} }
command_exists() {
if [ ! "$1" ]; then return 1; fi
command -v "$@" > /dev/null
}
is_root() {
if command_exists id && [ "$(id -u)" = 0 ]; then
return 0
fi
return 1
}
OS="$(os)" OS="$(os)"
main() { main() {
@@ -76,8 +64,8 @@ main() {
echo "USE AT YOUR OWN RISK!" echo "USE AT YOUR OWN RISK!"
fi fi
if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-20}" ]; then if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-18}" ]; then
echo "ERROR: code-server currently requires node v20." echo "ERROR: code-server currently requires node v18."
if [ -n "$FORCE_NODE_VERSION" ]; then if [ -n "$FORCE_NODE_VERSION" ]; then
echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION." echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION."
fi fi
@@ -87,20 +75,17 @@ main() {
exit 1 exit 1
fi fi
# Under npm, if we are running as root, we need --unsafe-perm otherwise case "${npm_config_user_agent-}" in npm*)
# post-install scripts will not have sufficient permissions to do their thing. # We are running under npm.
if is_root; then if [ "${npm_config_unsafe_perm-}" != "true" ]; then
case "${npm_config_user_agent-}" in npm*) echo "Please pass --unsafe-perm to npm to install code-server"
if [ "${npm_config_unsafe_perm-}" != "true" ]; then echo "Otherwise the postinstall script does not have permissions to run"
echo "Please pass --unsafe-perm to npm to install code-server" echo "See https://docs.npmjs.com/misc/config#unsafe-perm"
echo "Otherwise post-install scripts will not have permissions to run" echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm"
echo "See https://docs.npmjs.com/misc/config#unsafe-perm" exit 1
echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm" fi
exit 1 ;;
fi esac
;;
esac
fi
if ! vscode_install; then if ! vscode_install; then
echo "You may not have the required dependencies to build the native modules." echo "You may not have the required dependencies to build the native modules."

View File

@@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.20.0 version: 3.17.0
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using. # follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.89.1 appVersion: 4.21.0

View File

@@ -177,12 +177,9 @@ spec:
{{- if .existingClaim }} {{- if .existingClaim }}
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ .existingClaim }} claimName: {{ .existingClaim }}
{{- else if .hostPath }} {{- else }}
hostPath: hostPath:
path: {{ .hostPath }} path: {{ .hostPath }}
type: Directory type: Directory
{{- else }}
emptyDir:
{{- toYaml .emptyDir | nindent 10 }}
{{- end }} {{- end }}
{{- end }} {{- end }}

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image: image:
repository: codercom/code-server repository: codercom/code-server
tag: '4.89.1' tag: '4.21.0'
pullPolicy: Always pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a # Specifies one or more secrets to be used when pulling images from a
@@ -190,7 +190,6 @@ extraVolumeMounts: []
# readOnly: true # readOnly: true
# existingClaim: volume-claim # existingClaim: volume-claim
# hostPath: "" # hostPath: ""
# emptyDir: {}
extraConfigmapMounts: [] extraConfigmapMounts: []
# - name: certs-configmap # - name: certs-configmap

View File

@@ -35,7 +35,7 @@ RUN ARCH="$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')" \
&& printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml && printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
COPY ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh COPY ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh
RUN --mount=from=packages,src=/tmp,dst=/tmp/packages rpm -i /tmp/packages/code-server*$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g').rpm RUN --mount=from=packages,src=/tmp,dst=/tmp/packages dnf install -y /tmp/packages/code-server*$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g').rpm
# Allow users to have scripts run on container startup to prepare workspace. # Allow users to have scripts run on container startup to prepare workspace.
# https://github.com/coder/code-server/issues/5177 # https://github.com/coder/code-server/issues/5177

View File

@@ -18,7 +18,6 @@ group "default" {
targets = [ targets = [
"code-server-debian-12", "code-server-debian-12",
"code-server-ubuntu-focal", "code-server-ubuntu-focal",
"code-server-ubuntu-noble",
"code-server-fedora-39", "code-server-fedora-39",
"code-server-opensuse-tumbleweed", "code-server-opensuse-tumbleweed",
] ]
@@ -70,17 +69,6 @@ target "code-server-ubuntu-focal" {
platforms = ["linux/amd64", "linux/arm64"] platforms = ["linux/amd64", "linux/arm64"]
} }
target "code-server-ubuntu-noble" {
dockerfile = "ci/release-image/Dockerfile"
tags = concat(
gen_tags_for_docker_and_ghcr("noble"),
)
args = {
BASE = "ubuntu:noble"
}
platforms = ["linux/amd64", "linux/arm64"]
}
target "code-server-fedora-39" { target "code-server-fedora-39" {
dockerfile = "ci/release-image/Dockerfile.fedora" dockerfile = "ci/release-image/Dockerfile.fedora"
tags = concat( tags = concat(

View File

@@ -37,7 +37,7 @@ for [VS
Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites). Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Here is what is needed: Here is what is needed:
- `node` v20.x - `node` v18.x
- `git` v2.x or greater - `git` v2.x or greater
- [`git-lfs`](https://git-lfs.github.com) - [`git-lfs`](https://git-lfs.github.com)
- [`yarn`](https://classic.yarnpkg.com/en/) - [`yarn`](https://classic.yarnpkg.com/en/)

View File

@@ -356,12 +356,6 @@ hashed-password: "$argon2i$v=19$m=4096,t=3,p=1$wST5QhBgk2lu1ih4DMuxvg$LS1alrVdIW
The `hashed-password` field takes precedence over `password`. The `hashed-password` field takes precedence over `password`.
If you're using Docker Compose file, in order to make this work, you need to change all the single $ to $$. For example:
```yaml
- HASHED_PASSWORD=$$argon2i$$v=19$$m=4096,t=3,p=1$$wST5QhBgk2lu1ih4DMuxvg$$LS1alrVdIWtvZHwnzCM1DUGg+5DTO3Dt1d5v9XtLws4
```
## Is multi-tenancy possible? ## Is multi-tenancy possible?
If you want to run multiple code-servers on shared infrastructure, we recommend If you want to run multiple code-servers on shared infrastructure, we recommend

View File

@@ -11,14 +11,14 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
``` ```
6. Exit the terminal using `exit` and then reopen the terminal 6. Exit the terminal using `exit` and then reopen the terminal
7. Install and use Node.js 20: 7. Install and use Node.js 18:
```shell ```shell
nvm install 18 nvm install 18
nvm use 18 nvm use 18
``` ```
8. Install code-server globally on device with: `npm install --global code-server` 8. Install code-server globally on device with: `npm install --global code-server --unsafe-perm`
9. Run code-server with `code-server` 9. Run code-server with `code-server`
10. Access on localhost:8080 in your browser 10. Access on localhost:8080 in your browser

View File

@@ -33,16 +33,5 @@ resource "coder_app" "code-server" {
} }
``` ```
Or use our official [`code-server`](https://registry.coder.com/modules/code-server) module from the Coder [module registry](htpps://registry.coder.com/modules):
```terraform
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.5"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
}
```
If you run into issues, ask for help on the `coder/coder` [Discussions If you run into issues, ask for help on the `coder/coder` [Discussions
here](https://github.com/coder/coder/discussions). here](https://github.com/coder/coder/discussions).

View File

@@ -30,7 +30,7 @@ includes installing instructions based on your operating system.
## Node.js version ## Node.js version
We use the same major version of Node.js shipped with Code's remote, which is We use the same major version of Node.js shipped with Code's remote, which is
currently `20.x`. VS Code also [lists Node.js currently `18.x`. VS Code also [lists Node.js
requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites). requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Using other versions of Node.js [may lead to unexpected Using other versions of Node.js [may lead to unexpected
@@ -79,7 +79,7 @@ Proceed to [installing](#installing)
## FreeBSD ## FreeBSD
```sh ```sh
pkg install -y git python npm-node20 pkgconf pkg install -y git python npm-node18 pkgconf
pkg install -y libinotify pkg install -y libinotify
``` ```
@@ -92,7 +92,7 @@ Installing code-server requires all of the [prerequisites for VS Code developmen
Next, install code-server with: Next, install code-server with:
```bash ```bash
npm install --global code-server npm install --global code-server --unsafe-perm
code-server code-server
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
``` ```
@@ -112,7 +112,7 @@ For help and additional troubleshooting, see [#1397](https://github.com/coder/co
After adding the dependencies for your OS, install the code-server package globally: After adding the dependencies for your OS, install the code-server package globally:
```bash ```bash
npm install --global code-server npm install --global code-server --unsafe-perm
code-server code-server
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml # Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
``` ```
@@ -144,8 +144,8 @@ To debug installation issues, install with `npm`:
```shell ```shell
# Uninstall # Uninstall
npm uninstall --global code-server > /dev/null 2>&1 npm uninstall --global --unsafe-perm code-server > /dev/null 2>&1
# Install with logging # Install with logging
npm install --loglevel verbose --global code-server npm install --loglevel verbose --global --unsafe-perm code-server
``` ```

View File

@@ -57,7 +57,7 @@ npm config set python python3
node -v node -v
``` ```
you will get Node version `v20` you will get Node version `v18`
5. Now install code-server following our guide on [installing with npm](./npm.md) 5. Now install code-server following our guide on [installing with npm](./npm.md)
@@ -70,7 +70,7 @@ code-server --auth none
7. If already installed then use the following command for upgradation. 7. If already installed then use the following command for upgradation.
``` ```
npm update --global code-server npm update --global code-server --unsafe-perm
``` ```
## Upgrade ## Upgrade

17
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1681202837,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -20,11 +20,12 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1716137900, "lastModified": 1683594133,
"narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=", "narHash": "sha256-iUhLhEAgOCnexSGDsYT2ouydis09uDoNzM7UC685XGE=",
"path": "/nix/store/r8nhgnkxacbnf4kv8kdi8b6ks3k9b16i-source", "owner": "NixOS",
"rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1", "repo": "nixpkgs",
"type": "path" "rev": "8d447c5626cfefb9b129d5b30103344377fe09bc",
"type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",

View File

@@ -7,7 +7,7 @@
flake-utils.lib.eachDefaultSystem flake-utils.lib.eachDefaultSystem
(system: (system:
let pkgs = nixpkgs.legacyPackages.${system}; let pkgs = nixpkgs.legacyPackages.${system};
nodejs = pkgs.nodejs_20; nodejs = pkgs.nodejs-18_x;
yarn' = pkgs.yarn.override { inherit nodejs; }; yarn' = pkgs.yarn.override { inherit nodejs; };
in { in {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {

View File

@@ -441,7 +441,7 @@ install_npm() {
return return
fi fi
echoerr "Please install npm to install code-server!" echoerr "Please install npm to install code-server!"
echoerr "You will need at least node v20 and a few C dependencies." echoerr "You will need at least node v18 and a few C dependencies."
echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm" echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm"
exit 1 exit 1

View File

@@ -44,14 +44,14 @@
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/http-proxy": "1.17.7", "@types/http-proxy": "1.17.7",
"@types/js-yaml": "^4.0.6", "@types/js-yaml": "^4.0.6",
"@types/node": "20.x", "@types/node": "^18.0.0",
"@types/pem": "^1.14.1", "@types/pem": "^1.14.1",
"@types/proxy-from-env": "^1.0.1", "@types/proxy-from-env": "^1.0.1",
"@types/safe-compare": "^1.1.0", "@types/safe-compare": "^1.1.0",
"@types/semver": "^7.5.2", "@types/semver": "^7.5.2",
"@types/trusted-types": "^2.0.4", "@types/trusted-types": "^2.0.4",
"@types/ws": "^8.5.5", "@types/ws": "^8.5.5",
"@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2", "@typescript-eslint/parser": "^6.7.2",
"audit-ci": "^6.6.1", "audit-ci": "^6.6.1",
"doctoc": "^2.2.1", "doctoc": "^2.2.1",
@@ -61,7 +61,7 @@
"eslint-plugin-import": "^2.28.1", "eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^5.0.0", "eslint-plugin-prettier": "^5.0.0",
"prettier": "^3.0.3", "prettier": "^3.0.3",
"prettier-plugin-sh": "^0.14.0", "prettier-plugin-sh": "^0.13.1",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^5.2.2" "typescript": "^5.2.2"
}, },
@@ -71,7 +71,7 @@
"compression": "^1.7.4", "compression": "^1.7.4",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"env-paths": "^2.2.1", "env-paths": "^2.2.1",
"express": "5.0.0-beta.3", "express": "5.0.0-alpha.8",
"http-proxy": "^1.18.1", "http-proxy": "^1.18.1",
"httpolyglot": "^0.1.2", "httpolyglot": "^0.1.2",
"i18next": "^23.5.1", "i18next": "^23.5.1",
@@ -79,7 +79,7 @@
"limiter": "^2.1.0", "limiter": "^2.1.0",
"pem": "^1.14.8", "pem": "^1.14.8",
"proxy-agent": "^6.3.1", "proxy-agent": "^6.3.1",
"qs": "6.12.1", "qs": "6.9.7",
"rotating-file-stream": "^3.1.1", "rotating-file-stream": "^3.1.1",
"safe-buffer": "^5.2.1", "safe-buffer": "^5.2.1",
"safe-compare": "^1.1.4", "safe-compare": "^1.1.4",
@@ -88,7 +88,11 @@
"xdg-basedir": "^4.0.0" "xdg-basedir": "^4.0.0"
}, },
"resolutions": { "resolutions": {
"@types/node": "20.x" "@types/node": "^18.0.0",
"qs": "6.9.7"
},
"overrides": {
"qs": "6.9.7"
}, },
"bin": { "bin": {
"code-server": "out/node/entry.js" "code-server": "out/node/entry.js"
@@ -103,7 +107,7 @@
"remote-development" "remote-development"
], ],
"engines": { "engines": {
"node": "20" "node": "18"
}, },
"jest": { "jest": {
"transform": { "transform": {

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts --- code-server.orig/lib/vscode/src/vs/base/common/network.ts
+++ code-server/lib/vscode/src/vs/base/common/network.ts +++ code-server/lib/vscode/src/vs/base/common/network.ts
@@ -212,7 +212,9 @@ class RemoteAuthoritiesImpl { @@ -181,7 +181,9 @@ class RemoteAuthoritiesImpl {
return URI.from({ return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`, authority: `${host}:${port}`,
@@ -111,7 +111,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -270,16 +270,15 @@ export class WebClientServer { @@ -269,16 +269,15 @@ export class WebClientServer {
return void res.end(); return void res.end();
} }
@@ -133,20 +133,20 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
); );
if (!remoteAuthority) { if (!remoteAuthority) {
return serveError(req, res, 400, `Bad request.`); return serveError(req, res, 400, `Bad request.`);
@@ -306,8 +305,12 @@ export class WebClientServer { @@ -305,8 +304,12 @@ export class WebClientServer {
scopes: [['user:email'], ['repo']] scopes: [['user:email'], ['repo']]
} : undefined; } : undefined;
+ const base = relativeRoot(getOriginalUrl(req)) + const base = relativeRoot(getOriginalUrl(req))
+ const vscodeBase = relativePath(getOriginalUrl(req)) + const vscodeBase = relativePath(getOriginalUrl(req))
+ +
const productConfiguration = { const productConfiguration = <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion, codeServerVersion: this._productService.codeServerVersion,
+ rootEndpoint: base, + rootEndpoint: base,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? { extensionsGallery: this._webExtensionResourceUrlTemplate ? {
...this._productService.extensionsGallery, ...this._productService.extensionsGallery,
@@ -343,8 +346,10 @@ export class WebClientServer { @@ -341,8 +344,10 @@ export class WebClientServer {
const values: { [key: string]: string } = { const values: { [key: string]: string } = {
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration), WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '', WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
@@ -159,7 +159,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
}; };
if (useTestResolver) { if (useTestResolver) {
@@ -371,7 +376,7 @@ export class WebClientServer { @@ -369,7 +374,7 @@ export class WebClientServer {
'default-src \'self\';', 'default-src \'self\';',
'img-src \'self\' https: data: blob:;', 'img-src \'self\' https: data: blob:;',
'media-src \'self\';', 'media-src \'self\';',
@@ -168,7 +168,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
'child-src \'self\';', 'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`, `frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data: blob:;', 'worker-src \'self\' data: blob:;',
@@ -444,3 +449,70 @@ export class WebClientServer { @@ -442,3 +447,70 @@ export class WebClientServer {
return void res.end(data); return void res.end(data);
} }
} }
@@ -303,10 +303,10 @@ Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/ext
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { RemoteAuthorities } from 'vs/base/common/network'; -import { RemoteAuthorities } from 'vs/base/common/network';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
const WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT = '/web-extension-resource/'; @@ -102,7 +101,7 @@ export abstract class AbstractExtensionR
@@ -99,7 +98,7 @@ export abstract class AbstractExtensionR
: version, : version,
path: 'extension' path: 'extension'
})); }));

View File

@@ -17,7 +17,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -106,10 +106,14 @@ class RemoteTerminalBackend extends Base @@ -104,10 +104,14 @@ class RemoteTerminalBackend extends Base
} }
const reqId = e.reqId; const reqId = e.reqId;
const commandId = e.commandId; const commandId = e.commandId;

View File

@@ -1,136 +0,0 @@
Index: code-server/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
+++ code-server/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
@@ -8,6 +8,7 @@ import { isWeb } from 'vs/base/common/pl
import { isString } from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
+import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionManagementCLI } from 'vs/platform/extensionManagement/common/extensionManagementCLI';
@@ -89,6 +90,11 @@ CommandsRegistry.registerCommand('_remot
return lines.join('\n');
});
+CommandsRegistry.registerCommand('_remoteCLI.setClipboard', function (accessor: ServicesAccessor, content: string) {
+ const clipboardService = accessor.get(IClipboardService);
+ clipboardService.writeText(content);
+})
+
class RemoteExtensionManagementCLI extends ExtensionManagementCLI {
private _location: string | undefined;
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
@@ -43,7 +43,12 @@ export interface ExtensionManagementPipe
force?: boolean;
}
-export type PipeCommand = OpenCommandPipeArgs | StatusPipeArgs | OpenExternalCommandPipeArgs | ExtensionManagementPipeArgs;
+export interface ClipboardPipeArgs {
+ type: 'clipboard';
+ content: string;
+}
+
+export type PipeCommand = OpenCommandPipeArgs | StatusPipeArgs | OpenExternalCommandPipeArgs | ExtensionManagementPipeArgs | ClipboardPipeArgs;
export interface ICommandsExecuter {
executeCommand<T>(id: string, ...args: any[]): Promise<T>;
@@ -105,6 +110,9 @@ export class CLIServerBase {
case 'extensionManagement':
returnObj = await this.manageExtensions(data);
break;
+ case 'clipboard':
+ returnObj = await this.clipboard(data);
+ break;
default:
sendResponse(404, `Unknown message type: ${data.type}`);
break;
@@ -172,6 +180,10 @@ export class CLIServerBase {
return await this._commands.executeCommand<string | undefined>('_remoteCLI.getSystemStatus');
}
+ private async clipboard(data: ClipboardPipeArgs): Promise<undefined> {
+ return await this._commands.executeCommand('_remoteCLI.setClipboard', data.content);
+ }
+
dispose(): void {
this._server.close();
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -97,7 +97,7 @@ class RemoteTerminalBackend extends Base
}
});
- const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions'];
+ const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions', '_remoteCLI.setClipboard'];
this._remoteTerminalChannel.onExecuteCommand(async e => {
// Ensure this request for for this window
const pty = this._ptys.get(e.persistentProcessId);
Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
@@ -119,6 +119,7 @@ export interface NativeParsedArgs {
sandbox?: boolean;
'enable-coi'?: boolean;
+ 'stdin-to-clipboard'?: boolean;
// chromium command line args: https://electronjs.org/docs/all#supported-chrome-command-line-switches
'no-proxy-server'?: boolean;
Index: code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/node/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
@@ -90,6 +90,7 @@ export const OPTIONS: OptionDescriptions
'user-data-dir': { type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") },
'profile': { type: 'string', 'cat': 'o', args: 'profileName', description: localize('profileName', "Opens the provided folder or workspace with the given profile and associates the profile with the workspace. If the profile does not exist, a new empty one is created.") },
'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },
+ 'stdin-to-clipboard': { type: 'boolean', cat: 'o', alias: 'c', description: localize('clipboard', "copies the STDIN to the clipboard") },
'extensions-dir': { type: 'string', deprecates: ['extensionHomePath'], cat: 'e', args: 'dir', description: localize('extensionHomePath', "Set the root path for extensions.") },
'extensions-download-dir': { type: 'string' },
Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/server.cli.ts
+++ code-server/lib/vscode/src/vs/server/node/server.cli.ts
@@ -76,6 +76,7 @@ const isSupportedForPipe = (optionId: ke
case 'verbose':
case 'remote':
case 'locate-shell-integration-path':
+ case 'stdin-to-clipboard':
return true;
default:
return false;
@@ -293,6 +294,23 @@ export async function main(desc: Product
}
}
} else {
+ if (parsedArgs['stdin-to-clipboard']) {
+ if(!hasStdinWithoutTty()) {
+ console.error("stdin has a tty.");
+ return;
+ }
+ const fs = require("fs");
+ const stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
+ const clipboardContent = stdinBuffer.toString();
+ sendToPipe({
+ type: 'clipboard',
+ content: clipboardContent
+ }, verbose).catch(e => {
+ console.error('Error when requesting status:', e);
+ });
+ return;
+ }
+
if (parsedArgs.status) {
sendToPipe({
type: 'status'

View File

@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
@@ -285,6 +285,10 @@ export class Extension implements IExten @@ -249,6 +249,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') { if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false; return false;
} }

View File

@@ -23,14 +23,14 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -11,7 +11,7 @@ import * as path from 'vs/base/common/pa @@ -11,7 +11,7 @@ import * as path from 'vs/base/common/pa
import { IURITransformer } from 'vs/base/common/uriIpc'; import { IURITransformer } from 'vs/base/common/uriIpc';
import { getMachineId, getSqmMachineId, getdevDeviceId } from 'vs/base/node/id'; import { getMachineId, getSqmMachineId } from 'vs/base/node/id';
import { Promises } from 'vs/base/node/pfs'; import { Promises } from 'vs/base/node/pfs';
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; -import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
+import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; +import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
import { ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net'; import { ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService'; import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
@@ -238,6 +238,9 @@ export async function setupServerService @@ -228,6 +228,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)); const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel); socketServer.registerChannel('extensions', channel);
@@ -53,7 +53,7 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
export const LANGUAGE_DEFAULT = 'en'; export const LANGUAGE_DEFAULT = 'en';
let _isWindows = false; let _isWindows = false;
@@ -112,17 +110,21 @@ else if (typeof navigator === 'object' & @@ -111,17 +109,21 @@ else if (typeof navigator === 'object' &
_isMobile = _userAgent?.indexOf('Mobi') >= 0; _isMobile = _userAgent?.indexOf('Mobi') >= 0;
_isWeb = true; _isWeb = true;
@@ -218,9 +218,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
import { isString } from 'vs/base/common/types'; import { isString } from 'vs/base/common/types';
+import { getLocaleFromConfig, getNLSConfiguration } from 'vs/server/node/remoteLanguagePacks'; +import { getLocaleFromConfig, getNLSConfiguration } from 'vs/server/node/remoteLanguagePacks';
import { CharCode } from 'vs/base/common/charCode'; import { CharCode } from 'vs/base/common/charCode';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions'; import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
@@ -345,6 +346,8 @@ export class WebClientServer {
@@ -348,6 +349,8 @@ export class WebClientServer {
callbackRoute: this._callbackRoute callbackRoute: this._callbackRoute
}; };
@@ -229,7 +229,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl; const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl;
const values: { [key: string]: string } = { const values: { [key: string]: string } = {
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration), WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
@@ -356,6 +359,7 @@ export class WebClientServer { @@ -353,6 +356,7 @@ export class WebClientServer {
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''), WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
BASE: base, BASE: base,
VS_BASE: vscodeBase, VS_BASE: vscodeBase,
@@ -249,8 +249,8 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -103,6 +104,7 @@ export interface ServerParsedArgs { @@ -102,6 +103,7 @@ export interface ServerParsedArgs {
'auth'?: string; 'auth'?: string
'disable-file-downloads'?: boolean; 'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean; 'disable-file-uploads'?: boolean;
+ 'locale'?: string + 'locale'?: string
@@ -261,7 +261,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts --- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts +++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
@@ -52,7 +52,7 @@ import 'vs/workbench/services/dialogs/br @@ -50,7 +50,7 @@ import 'vs/workbench/services/dialogs/br
import 'vs/workbench/services/host/browser/browserHostService'; import 'vs/workbench/services/host/browser/browserHostService';
import 'vs/workbench/services/lifecycle/browser/lifecycleService'; import 'vs/workbench/services/lifecycle/browser/lifecycleService';
import 'vs/workbench/services/clipboard/browser/clipboardService'; import 'vs/workbench/services/clipboard/browser/clipboardService';
@@ -270,7 +270,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
import 'vs/workbench/services/path/browser/pathService'; import 'vs/workbench/services/path/browser/pathService';
import 'vs/workbench/services/themes/browser/browserHostColorSchemeService'; import 'vs/workbench/services/themes/browser/browserHostColorSchemeService';
import 'vs/workbench/services/encryption/browser/encryptionService'; import 'vs/workbench/services/encryption/browser/encryptionService';
@@ -118,8 +118,9 @@ registerSingleton(ILanguagePackService, @@ -116,8 +116,9 @@ registerSingleton(ILanguagePackService,
// Logs // Logs
import 'vs/workbench/contrib/logs/browser/logs.contribution'; import 'vs/workbench/contrib/logs/browser/logs.contribution';
@@ -348,7 +348,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
@@ -341,9 +341,6 @@ export class InstallAction extends Exten @@ -338,9 +338,6 @@ export class InstallAction extends Exten
if (this.extension.isBuiltin) { if (this.extension.isBuiltin) {
return; return;
} }
@@ -358,7 +358,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) { if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) {
this.enabled = this.options.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion; this.enabled = this.options.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion;
this.updateLabel(); this.updateLabel();
@@ -614,7 +611,7 @@ export abstract class InstallInOtherServ @@ -608,7 +605,7 @@ export abstract class InstallInOtherServ
} }
if (isLanguagePackExtension(this.extension.local.manifest)) { if (isLanguagePackExtension(this.extension.local.manifest)) {
@@ -367,7 +367,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
} }
// Prefers to run on UI // Prefers to run on UI
@@ -1848,17 +1845,6 @@ export class SetLanguageAction extends E @@ -1780,17 +1777,6 @@ export class SetLanguageAction extends E
update(): void { update(): void {
this.enabled = false; this.enabled = false;
this.class = SetLanguageAction.DisabledClass; this.class = SetLanguageAction.DisabledClass;
@@ -385,7 +385,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
} }
override async run(): Promise<any> { override async run(): Promise<any> {
@@ -1875,7 +1861,6 @@ export class ClearLanguageAction extends @@ -1807,7 +1793,6 @@ export class ClearLanguageAction extends
private static readonly DisabledClass = `${ClearLanguageAction.EnabledClass} disabled`; private static readonly DisabledClass = `${ClearLanguageAction.EnabledClass} disabled`;
constructor( constructor(
@@ -393,7 +393,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
@ILocaleService private readonly localeService: ILocaleService, @ILocaleService private readonly localeService: ILocaleService,
) { ) {
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false); super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
@@ -1885,17 +1870,6 @@ export class ClearLanguageAction extends @@ -1817,17 +1802,6 @@ export class ClearLanguageAction extends
update(): void { update(): void {
this.enabled = false; this.enabled = false;
this.class = ClearLanguageAction.DisabledClass; this.class = ClearLanguageAction.DisabledClass;

View File

@@ -27,7 +27,7 @@ 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.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -303,6 +303,16 @@ export interface IWorkbenchConstructionO @@ -282,6 +282,16 @@ export interface IWorkbenchConstructionO
*/ */
readonly userDataPath?: string readonly userDataPath?: string
@@ -99,10 +99,10 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -99,6 +101,8 @@ export interface ServerParsedArgs { @@ -98,6 +100,8 @@ export interface ServerParsedArgs {
/* ----- code-server ----- */ /* ----- code-server ----- */
'disable-update-check'?: boolean; 'disable-update-check'?: boolean;
'auth'?: string; 'auth'?: string
+ 'disable-file-downloads'?: boolean; + 'disable-file-downloads'?: boolean;
+ 'disable-file-uploads'?: boolean; + 'disable-file-uploads'?: boolean;
@@ -112,8 +112,8 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -334,6 +334,8 @@ export class WebClientServer { @@ -332,6 +332,8 @@ export class WebClientServer {
serverBasePath: this._basePath, remoteAuthority,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath, userDataPath: this._environmentService.userDataPath,
+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], + isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
@@ -125,30 +125,31 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,11 +7,11 @@ import { Event } from 'vs/base/common/ev @@ -7,12 +7,12 @@ import { Event } from 'vs/base/common/ev
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys'; import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-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 } from 'vs/workbench/common/contextkeys'; -import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, MainEditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, ActiveEditorCanToggleReadonlyContext, applyAvailableEditorIds, TitleBarVisibleContext, TitleBarStyleContext, MultipleEditorGroupsContext, IsAuxiliaryWindowFocusedContext, ActiveCompareEditorOriginalWriteableContext } from 'vs/workbench/common/contextkeys';
+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, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys'; +import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, MainEditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, ActiveEditorCanToggleReadonlyContext, applyAvailableEditorIds, TitleBarVisibleContext, TitleBarStyleContext, MultipleEditorGroupsContext, IsAuxiliaryWindowFocusedContext, ActiveCompareEditorOriginalWriteableContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom'; import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; +import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace'; import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService'; import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; @@ -87,7 +87,7 @@ export class WorkbenchContextKeysHandler
@@ -70,7 +70,7 @@ export class WorkbenchContextKeysHandler
@IContextKeyService private readonly contextKeyService: IContextKeyService, @IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService, @IConfigurationService private readonly configurationService: IConfigurationService,
- @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, - @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
+ @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, + @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
@IProductService private readonly productService: IProductService, @IProductService private readonly productService: IProductService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IEditorService private readonly editorService: IEditorService, @IEditorService private readonly editorService: IEditorService,
@@ -197,6 +197,10 @@ export class WorkbenchContextKeysHandler @IEditorResolverService private readonly editorResolverService: IEditorResolverService,
@@ -224,6 +224,10 @@ export class WorkbenchContextKeysHandler
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService); this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART)); this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
@@ -167,12 +168,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
-import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext } from 'vs/workbench/common/contextkeys'; -import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext } from 'vs/workbench/common/contextkeys';
+import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys'; +import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables'; import { ThemeIcon } from 'vs/base/common/themables';
@@ -561,13 +561,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo @@ -550,13 +550,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID, id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL title: DOWNLOAD_LABEL
}, },
@@ -196,7 +197,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
) )
})); }));
@@ -579,6 +582,7 @@ MenuRegistry.appendMenuItem(MenuId.Explo @@ -568,6 +571,7 @@ MenuRegistry.appendMenuItem(MenuId.Explo
title: UPLOAD_LABEL, title: UPLOAD_LABEL,
}, },
when: ContextKeyExpr.and( when: ContextKeyExpr.and(
@@ -281,7 +282,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
@@ -65,6 +65,7 @@ import { timeout } from 'vs/base/common/ @@ -68,6 +68,7 @@ import { HoverPosition } from 'vs/base/b
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { mainWindow } from 'vs/base/browser/window'; import { mainWindow } from 'vs/base/browser/window';
import { IExplorerFileContribution, explorerFileContribRegistry } from 'vs/workbench/contrib/files/browser/explorerFileContrib'; import { IExplorerFileContribution, explorerFileContribRegistry } from 'vs/workbench/contrib/files/browser/explorerFileContrib';
@@ -289,7 +290,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
export class ExplorerDelegate implements IListVirtualDelegate<ExplorerItem> { export class ExplorerDelegate implements IListVirtualDelegate<ExplorerItem> {
@@ -1001,7 +1002,8 @@ export class FileDragAndDrop implements @@ -1079,7 +1080,8 @@ export class FileDragAndDrop implements
@IConfigurationService private configurationService: IConfigurationService, @IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService, @IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
@@ -299,7 +300,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
) { ) {
const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => { const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => {
if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) { if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) {
@@ -1226,15 +1228,17 @@ export class FileDragAndDrop implements @@ -1284,15 +1286,17 @@ export class FileDragAndDrop implements
// External file DND (Import/Upload file) // External file DND (Import/Upload file)
if (data instanceof NativeDragAndDropData) { if (data instanceof NativeDragAndDropData) {

View File

@@ -14,12 +14,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
-import { $, Dimension, addDisposableListener, append, clearNode, reset } from 'vs/base/browser/dom'; -import { $, Dimension, addDisposableListener, append, clearNode, getWindow, reset } from 'vs/base/browser/dom';
+import { $, Dimension, addDisposableListener, append, clearNode, reset, prepend } from 'vs/base/browser/dom'; +import { $, Dimension, addDisposableListener, append, clearNode, getWindow, reset, prepend } from 'vs/base/browser/dom';
import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer'; import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Button } from 'vs/base/browser/ui/button/button'; import { Button } from 'vs/base/browser/ui/button/button';
@@ -54,7 +54,7 @@ import { IRecentFolder, IRecentWorkspace @@ -58,7 +58,7 @@ import { IRecentFolder, IRecentWorkspace
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions'; import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
@@ -27,8 +27,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys'; +import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
import { IEditorOpenContext, IEditorSerializer } from 'vs/workbench/common/editor'; import { IEditorOpenContext, IEditorSerializer } from 'vs/workbench/common/editor';
import { IWebviewElement, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { IWebviewElement, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedColors'; import { IFeaturedExtensionsService } from 'vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService';
@@ -816,6 +816,72 @@ export class GettingStartedPage extends @@ -793,6 +793,72 @@ export class GettingStartedPage extends
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved")) $('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
); );
@@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
const leftColumn = $('.categories-column.categories-column-left', {},); const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},); const rightColumn = $('.categories-column.categories-column-right', {},);
@@ -887,6 +953,9 @@ export class GettingStartedPage extends @@ -842,6 +908,9 @@ export class GettingStartedPage extends
recentList.setLimit(5); recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
} }
@@ -110,7 +110,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
+ } + }
}; };
gettingStartedList.onDidChange(layoutLists); featuredExtensionList.onDidChange(layoutFeaturedExtension);
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css 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.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
@@ -135,7 +135,7 @@ 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.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/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 @@ -292,6 +292,11 @@ export interface IWorkbenchConstructionO
*/ */
readonly isEnabledFileUploads?: boolean readonly isEnabledFileUploads?: boolean
@@ -189,7 +189,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -105,6 +106,7 @@ export interface ServerParsedArgs { @@ -104,6 +105,7 @@ export interface ServerParsedArgs {
'disable-file-downloads'?: boolean; 'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean; 'disable-file-uploads'?: boolean;
'locale'?: string 'locale'?: string
@@ -201,7 +201,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -339,6 +339,7 @@ export class WebClientServer { @@ -336,6 +336,7 @@ export class WebClientServer {
userDataPath: this._environmentService.userDataPath, userDataPath: this._environmentService.userDataPath,
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'], isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
@@ -217,12 +217,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys'; import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-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, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys'; -import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, MainEditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, ActiveEditorCanToggleReadonlyContext, applyAvailableEditorIds, TitleBarVisibleContext, TitleBarStyleContext, MultipleEditorGroupsContext, IsAuxiliaryWindowFocusedContext, ActiveCompareEditorOriginalWriteableContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
+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, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from 'vs/workbench/common/contextkeys'; +import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, MainEditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, ActiveEditorCanToggleReadonlyContext, applyAvailableEditorIds, TitleBarVisibleContext, TitleBarStyleContext, MultipleEditorGroupsContext, IsAuxiliaryWindowFocusedContext, ActiveCompareEditorOriginalWriteableContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom'; import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -227,6 +227,7 @@ export class WorkbenchContextKeysHandler
@@ -200,6 +200,7 @@ export class WorkbenchContextKeysHandler
// code-server // code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true) IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true) IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)

View File

@@ -184,7 +184,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IProgressService } from 'vs/platform/progress/common/progress'; import { IProgressService } from 'vs/platform/progress/common/progress';
import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel'; import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel';
@@ -131,6 +132,9 @@ export class BrowserMain extends Disposa @@ -130,6 +131,9 @@ export class BrowserMain extends Disposa
// Startup // Startup
const instantiationService = workbench.startup(); const instantiationService = workbench.startup();
@@ -264,11 +264,11 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -307,6 +307,7 @@ export class WebClientServer { @@ -306,6 +306,7 @@ export class WebClientServer {
} : undefined; } : undefined;
const productConfiguration = { const productConfiguration = <Partial<IProductConfiguration>>{
+ codeServerVersion: this._productService.codeServerVersion, + codeServerVersion: this._productService.codeServerVersion,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? { extensionsGallery: this._webExtensionResourceUrlTemplate ? {
...this._productService.extensionsGallery, ...this._productService.extensionsGallery,

View File

@@ -1,15 +0,0 @@
This can be removed after upgrading to Node >= 19 as keepAlive is defaulted to
true after 19.
Index: code-server/lib/vscode/src/vs/platform/request/node/proxy.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/request/node/proxy.ts
+++ code-server/lib/vscode/src/vs/platform/request/node/proxy.ts
@@ -42,6 +42,7 @@ export async function getProxyAgent(rawR
port: (proxyEndpoint.port ? +proxyEndpoint.port : 0) || (proxyEndpoint.protocol === 'https' ? 443 : 80),
auth: proxyEndpoint.auth,
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true,
+ keepAlive: true,
};
return requestURL.protocol === 'http:'

View File

@@ -18,9 +18,9 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -329,6 +329,7 @@ export class WebClientServer { @@ -327,6 +327,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority, remoteAuthority,
serverBasePath: this._basePath,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
+ userDataPath: this._environmentService.userDataPath, + userDataPath: this._environmentService.userDataPath,
_wrapWebWorkerExtHostInIframe, _wrapWebWorkerExtHostInIframe,
@@ -30,7 +30,7 @@ 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.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO @@ -277,6 +277,11 @@ export interface IWorkbenchConstructionO
*/ */
readonly configurationDefaults?: Record<string, any>; readonly configurationDefaults?: Record<string, any>;

View File

@@ -28,11 +28,11 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -97,6 +98,7 @@ export const serverOptions: OptionDescri @@ -96,6 +97,7 @@ export const serverOptions: OptionDescri
export interface ServerParsedArgs { export interface ServerParsedArgs {
/* ----- code-server ----- */ /* ----- code-server ----- */
'disable-update-check'?: boolean; 'disable-update-check'?: boolean;
+ 'auth'?: string; + 'auth'?: string
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -40,14 +40,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -312,6 +312,7 @@ export class WebClientServer { @@ -311,6 +311,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion, codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base, rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
+ logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, + logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery, extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts

View File

@@ -40,8 +40,8 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -114,7 +114,7 @@ export class WebClientServer { @@ -113,7 +113,7 @@ export class WebClientServer {
const serverRootPath = getRemoteServerRootPath(_productService);
this._staticRoute = `${serverRootPath}/static`; this._staticRoute = `${serverRootPath}/static`;
this._callbackRoute = `${serverRootPath}/callback`; this._callbackRoute = `${serverRootPath}/callback`;
- this._webExtensionRoute = `${serverRootPath}/web-extension-resource`; - this._webExtensionRoute = `${serverRootPath}/web-extension-resource`;
@@ -49,51 +49,40 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
} }
/** /**
@@ -312,14 +312,7 @@ export class WebClientServer { @@ -311,14 +311,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion, codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base, rootEndpoint: base,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
- extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? { - extensionsGallery: this._webExtensionResourceUrlTemplate ? {
- ...this._productService.extensionsGallery, - ...this._productService.extensionsGallery,
- resourceUrlTemplate: this._webExtensionResourceUrlTemplate.with({ - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({
- scheme: 'http', - scheme: 'http',
- authority: remoteAuthority, - authority: remoteAuthority,
- path: `${this._webExtensionRoute}/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}` - path: `${this._webExtensionRoute}/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}`
- }).toString(true) - }).toString(true)
- } : undefined - } : undefined
+ extensionsGallery: this._productService.extensionsGallery, + extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };
if (!this._environmentService.isBuilt) { if (!this._environmentService.isBuilt) {
Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts --- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts +++ code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
@@ -140,9 +140,9 @@ export abstract class AbstractExtensionR @@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/
} import { IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
protected _isWebExtensionResourceEndPoint(uri: URI): boolean { import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
- const uriPath = uri.path, serverRootPath = RemoteAuthorities.getServerRootPath(); -import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
- // test if the path starts with the server root path followed by the web extension resource end point segment import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
- return uriPath.startsWith(serverRootPath) && uriPath.startsWith(WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT, serverRootPath.length);
+ const uriPath = uri.path;
+ // test if the path starts with the web extension resource end point segment
+ return uriPath.startsWith(WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT);
}
}
Index: code-server/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
@@ -114,7 +114,10 @@ export class ExtensionsDownloader extend
return false;
}
+ return false
+ // @ts-expect-error
const value = this.configurationService.getValue('extensions.verifySignature');
+ // @ts-expect-error
return isBoolean(value) ? value : true;
}
const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource';
@@ -77,7 +76,7 @@ export abstract class AbstractExtensionR
private readonly _environmentService: IEnvironmentService,
private readonly _configurationService: IConfigurationService,
) {
- this._webExtensionResourceEndPoint = `${getRemoteServerRootPath(_productService)}/${WEB_EXTENSION_RESOURCE_END_POINT}/`;
+ this._webExtensionResourceEndPoint = `/${WEB_EXTENSION_RESOURCE_END_POINT}/`;
if (_productService.extensionsGallery) {
this._extensionGalleryResourceUrlTemplate = _productService.extensionsGallery.resourceUrlTemplate;
this._extensionGalleryAuthority = this._extensionGalleryResourceUrlTemplate ? this._getExtensionGalleryAuthority(URI.parse(this._extensionGalleryResourceUrlTemplate)) : undefined;

View File

@@ -42,16 +42,16 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts --- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
@@ -35,7 +35,7 @@ export class RemoteAuthorityResolverServ @@ -34,7 +34,7 @@ export class RemoteAuthorityResolverServ
isWorkbenchOptionsBasedResolution: boolean,
connectionToken: Promise<string> | string | undefined, connectionToken: Promise<string> | string | undefined,
resourceUriProvider: ((uri: URI) => URI) | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined,
serverBasePath: string | undefined,
- @IProductService productService: IProductService, - @IProductService productService: IProductService,
+ @IProductService private readonly productService: IProductService, + @IProductService private readonly productService: IProductService,
@ILogService private readonly _logService: ILogService, @ILogService private readonly _logService: ILogService,
) { ) {
super(); super();
@@ -86,9 +86,14 @@ export class RemoteAuthorityResolverServ @@ -85,9 +85,14 @@ export class RemoteAuthorityResolverServ
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken); const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`); performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`);
this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`); this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`);
@@ -71,19 +71,19 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -313,6 +313,7 @@ export class WebClientServer { @@ -312,6 +312,7 @@ export class WebClientServer {
rootEndpoint: base, rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
+ proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/', + proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery, extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
@@ -291,7 +291,7 @@ export async function createTerminalEnvi @@ -271,7 +271,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment // Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables // variables
@@ -148,9 +148,9 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExpl
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts --- code-server.orig/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
@@ -77,7 +77,7 @@ export class ForwardedPortsView extends @@ -80,7 +80,7 @@ export class ForwardedPortsView extends
private async enableForwardedPortsView() { this.contextKeyListener = undefined;
this.contextKeyListener.clear(); }
- const viewEnabled: boolean = !!forwardedPortsViewEnabled.getValue(this.contextKeyService); - const viewEnabled: boolean = !!forwardedPortsViewEnabled.getValue(this.contextKeyService);
+ const viewEnabled: boolean = true; + const viewEnabled: boolean = true;

View File

@@ -19,5 +19,3 @@ display-language.diff
cli-window-open.diff cli-window-open.diff
getting-started.diff getting-started.diff
safari.diff safari.diff
keepalive.diff
clipboard.diff

View File

@@ -54,7 +54,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -314,6 +314,10 @@ export class WebClientServer { @@ -313,6 +313,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/', proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
@@ -64,4 +64,4 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
+ }, + },
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery, extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/build/gulpfile.reh.js --- code-server.orig/lib/vscode/build/gulpfile.reh.js
+++ code-server/lib/vscode/build/gulpfile.reh.js +++ code-server/lib/vscode/build/gulpfile.reh.js
@@ -236,8 +236,7 @@ function packageTask(type, platform, arc @@ -235,8 +235,7 @@ function packageTask(type, platform, arc
const src = gulp.src(sourceFolderName + '/**', { base: '.' }) const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest) => { const isUIExtension = (manifest) => {
@@ -276,9 +275,9 @@ function packageTask(type, platform, arc @@ -275,9 +274,9 @@ function packageTask(type, platform, arc
.map(name => `.build/extensions/${name}/**`); .map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version; let version = packageJson.version;
const quality = product.quality; const quality = product.quality;
@@ -439,7 +438,7 @@ function tweakProductForServerWeb(produc @@ -432,7 +431,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series( const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask, optimizeTask,
util.rimraf(`out-vscode-${type}-min`), util.rimraf(`out-vscode-${type}-min`),

View File

@@ -20,96 +20,60 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
import { NullPolicyService } from 'vs/platform/policy/common/policy'; import { NullPolicyService } from 'vs/platform/policy/common/policy';
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
import { LoggerService } from 'vs/platform/log/node/loggerService'; import { LoggerService } from 'vs/platform/log/node/loggerService';
@@ -147,11 +148,23 @@ export async function setupServerService @@ -149,7 +150,10 @@ export async function setupServerService
const requestService = new RequestService(configurationService, environmentService, logService, loggerService);
services.set(IRequestService, requestService);
+ let isContainer = undefined;
+ try {
+ await Promises.stat('/run/.containerenv');
+ isContainer = true;
+ } catch (error) { /* Does not exist, probably. */ }
+ if (!isContainer) {
+ try {
+ const content = await Promises.readFile('/proc/self/cgroup', 'utf8')
+ isContainer = content.includes('docker');
+ } catch (error) { /* Permission denied, probably. */ }
+ }
+
let oneDsAppender: ITelemetryAppender = NullAppender; let oneDsAppender: ITelemetryAppender = NullAppender;
const isInternal = isInternalTelemetry(productService, configurationService); const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) { if (supportsTelemetry(productService, environmentService)) {
- if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) { - if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) {
- oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, productService.aiConfig.ariaKey); + const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
+ if (!isLoggingOnly(productService, environmentService) && productService.telemetryEndpoint) { + if (telemetryEndpoint) {
+ oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, () => new TelemetryClient(productService.telemetryEndpoint!, machineId, isContainer)); + oneDsAppender = new OneDataSystemAppender(requestService, false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint));
+ } else if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) {
oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
} }
Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts +++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
@@ -0,0 +1,71 @@ @@ -0,0 +1,49 @@
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js'; +import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
+import * as https from 'https'; +import * as https from 'https';
+import * as http from 'http'; +import * as http from 'http';
+import * as os from 'os'; +import * as os from 'os';
+ +
+interface SystemInfo {
+ measurements: Record<string, number | undefined>;
+ properties: Record<string, string | boolean | null | undefined>;
+}
+
+export class TelemetryClient extends AppInsightsCore { +export class TelemetryClient extends AppInsightsCore {
+ private readonly systemInfo: SystemInfo = { + public constructor(private readonly endpoint: string) {
+ measurements: {},
+ properties: {},
+ };
+
+ public constructor(
+ private readonly endpoint: string,
+ machineId: string,
+ isContainer: boolean | undefined) {
+ super(); + super();
+
+ // os.cpus() can take a very long time sometimes (personally I see 1-2
+ // seconds in a Coder workspace). This adds up significantly, especially
+ // when many telemetry requests are sent during startup, which can cause
+ // connection timeouts. Try to cache as much as we can.
+ try {
+ const cpus = os.cpus();
+ this.systemInfo.measurements.cores = cpus.length;
+ this.systemInfo.properties['common.cpuModel'] = cpus[0].model;
+ } catch (error) {}
+
+ try {
+ this.systemInfo.properties['common.shell'] = os.userInfo().shell;
+ this.systemInfo.properties['common.release'] = os.release();
+ this.systemInfo.properties['common.arch'] = os.arch();
+ } catch (error) {}
+
+ this.systemInfo.properties['common.remoteMachineId'] = machineId;
+ this.systemInfo.properties['common.isContainer'] = isContainer;
+ } + }
+ +
+ public override track(item: IExtendedTelemetryItem | ITelemetryItem): void { + public override track(item: IExtendedTelemetryItem | ITelemetryItem): void {
+ const options = item.baseData || {} + const options = item.baseData || {}
+ options.measurements = { + if (!options.properties) {
+ ...(options.measurements || {}), + options.properties = {};
+ ...this.systemInfo.measurements,
+ } + }
+ options.properties = { + if (!options.measurements) {
+ ...(options.properties || {}), + options.measurements = {};
+ ...this.systemInfo.properties,
+ } + }
+ +
+ try { + try {
+ const cpus = os.cpus();
+ options.measurements.cores = cpus.length;
+ options.properties['common.cpuModel'] = cpus[0].model;
+ } catch (error) {}
+
+ try {
+ options.measurements.memoryFree = os.freemem(); + options.measurements.memoryFree = os.freemem();
+ options.measurements.memoryTotal = os.totalmem(); + options.measurements.memoryTotal = os.totalmem();
+ } catch (error) {} + } catch (error) {}
+ +
+ try { + try {
+ options.properties['common.shell'] = os.userInfo().shell;
+ options.properties['common.release'] = os.release();
+ options.properties['common.arch'] = os.arch();
+ } catch (error) {}
+
+ try {
+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, { + const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
+ method: 'POST', + method: 'POST',
+ headers: { + headers: {
@@ -126,38 +90,11 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -318,6 +318,8 @@ export class WebClientServer { @@ -317,6 +317,7 @@ export class WebClientServer {
scope: vscodeBase + '/', scope: vscodeBase + '/',
path: base + '/_static/out/browser/serviceWorker.js', path: base + '/_static/out/browser/serviceWorker.js',
}, },
+ enableTelemetry: this._productService.enableTelemetry, + enableTelemetry: this._productService.enableTelemetry,
+ telemetryEndpoint: this._productService.telemetryEndpoint,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery, extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };
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
@@ -64,6 +64,7 @@ export interface IProductConfiguration {
readonly path: string;
readonly scope: string;
}
+ readonly telemetryEndpoint?: string
readonly version: string;
readonly date?: string;
Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -55,7 +55,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
controlUrl: "",
recommendationsUrl: "",
- })
+ }),
+ telemetryEndpoint: env.CS_TELEMETRY_URL || product.telemetryEndpoint || "https://v1.telemetry.coder.com/track",
});
}

View File

@@ -105,14 +105,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -311,6 +311,7 @@ export class WebClientServer { @@ -310,6 +310,7 @@ export class WebClientServer {
const productConfiguration = { const productConfiguration = <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion, codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base, rootEndpoint: base,
+ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
embedderIdentifier: 'server-distro', embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery, extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>; };
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -93,6 +95,8 @@ export const serverOptions: OptionDescri @@ -92,6 +94,8 @@ export const serverOptions: OptionDescri
}; };
export interface ServerParsedArgs { export interface ServerParsedArgs {

View File

@@ -54,10 +54,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
=================================================================== ===================================================================
--- code-server.orig/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 +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -325,6 +325,7 @@ export class WebClientServer { @@ -323,6 +323,7 @@ export class WebClientServer {
const workbenchWebConfiguration = { const workbenchWebConfiguration = {
remoteAuthority, remoteAuthority,
serverBasePath: this._basePath,
+ webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', + webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
_wrapWebWorkerExtHostInIframe, _wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() }, developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
@@ -70,12 +70,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" <meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-bQPwjO6bLiyf6v9eDVtAI67LrfonA1w49aFkRXBy4/g=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> - content="default-src 'none'; script-src 'sha256-frEVWVmmI4TWHGHXZaCTWqGQI9jv+i8hv+sOa87Gqlc=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-R3BsSkqy7qFbvWSmwr7WqT1eg6Sq4zSe0uIlrUQ4EKE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> + content="default-src 'none'; script-src 'sha256-1BNp/IJ0Swu9k0gYe2BJz18zVYJ4emIdN3fjPgGScQI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming --> <!-- Disable pinch zooming -->
<meta name="viewport" <meta name="viewport"
@@ -344,6 +344,12 @@ @@ -339,6 +339,12 @@
const hostname = location.hostname; const hostname = location.hostname;
@@ -92,7 +92,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html --- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -343,6 +343,12 @@ @@ -338,6 +338,12 @@
const hostname = location.hostname; const hostname = location.hostname;

View File

@@ -833,8 +833,8 @@ export interface CodeArgs extends UserProvidedCodeArgs {
version: boolean version: boolean
"without-connection-token"?: boolean "without-connection-token"?: boolean
"without-browser-env-var"?: boolean "without-browser-env-var"?: boolean
compatibility?: string compatibility: string
log?: string[] log: string[] | undefined
} }
/** /**
@@ -843,12 +843,15 @@ export interface CodeArgs extends UserProvidedCodeArgs {
export type SpawnCodeCli = (args: CodeArgs) => Promise<void> export type SpawnCodeCli = (args: CodeArgs) => Promise<void>
/** /**
* Convert our arguments to equivalent VS Code server arguments. * Convert our arguments to VS Code server arguments.
* Does not add any extra arguments.
*/ */
export const toCodeArgs = async (args: DefaultedArgs): Promise<CodeArgs> => { export const toCodeArgs = async (args: DefaultedArgs): Promise<CodeArgs> => {
return { return {
...args, ...args,
"accept-server-license-terms": true,
// This seems to be used to make the connection token flags optional (when
// set to 1.63) but we have always included them.
compatibility: "1.64",
/** Type casting. */ /** Type casting. */
help: !!args.help, help: !!args.help,
version: !!args.version, version: !!args.version,

View File

@@ -319,8 +319,8 @@ export const getCookieOptions = (req: express.Request): express.CookieOptions =>
// URL of that page) and the relative path to the root as given to it by the // URL of that page) and the relative path to the root as given to it by the
// backend. Using these two we can determine the true absolute root. // backend. Using these two we can determine the true absolute root.
const url = new URL( const url = new URL(
req.query.base || req.body?.base || "/", req.query.base || req.body.base || "/",
req.query.href || req.body?.href || "http://" + (req.headers.host || "localhost"), req.query.href || req.body.href || "http://" + (req.headers.host || "localhost"),
) )
return { return {
domain: getCookieDomain(url.host, req.args["proxy-domain"]), domain: getCookieDomain(url.host, req.args["proxy-domain"]),

View File

@@ -52,17 +52,12 @@ export const runCodeCli = async (args: DefaultedArgs): Promise<void> => {
try { try {
await spawnCli(await toCodeArgs(args)) await spawnCli(await toCodeArgs(args))
// Rather than have the caller handle errors and exit, spawnCli will exit
// itself. Additionally, it does this on a timeout set to 0. So, try
// waiting for VS Code to exit before giving up and doing it ourselves.
await new Promise((r) => setTimeout(r, 1000))
logger.warn("Code never exited")
process.exit(0)
} catch (error: any) { } catch (error: any) {
// spawnCli catches all errors, but just in case that changes.
logger.error("Got error from Code", error) logger.error("Got error from Code", error)
process.exit(1) process.exit(1)
} }
process.exit(0)
} }
export const openInExistingInstance = async (args: DefaultedArgs, socketPath: string): Promise<void> => { export const openInExistingInstance = async (args: DefaultedArgs, socketPath: string): Promise<void> => {

View File

@@ -53,7 +53,7 @@ const maybeProxy = (req: Request): string | undefined => {
return undefined return undefined
} }
router.all(/.*/, async (req, res, next) => { router.all("*", async (req, res, next) => {
const port = maybeProxy(req) const port = maybeProxy(req)
if (!port) { if (!port) {
return next() return next()
@@ -97,7 +97,7 @@ router.all(/.*/, async (req, res, next) => {
export const wsRouter = WsRouter() export const wsRouter = WsRouter()
wsRouter.ws(/.*/, async (req, _, next) => { wsRouter.ws("*", async (req, _, next) => {
const port = maybeProxy(req) const port = maybeProxy(req)
if (!port) { if (!port) {
return next() return next()

View File

@@ -25,7 +25,7 @@ import * as login from "./login"
import * as logout from "./logout" import * as logout from "./logout"
import * as pathProxy from "./pathProxy" import * as pathProxy from "./pathProxy"
import * as update from "./update" import * as update from "./update"
import * as vscode from "./vscode" import { CodeServerRouteWrapper } from "./vscode"
/** /**
* Register all routes and middleware. * Register all routes and middleware.
@@ -109,21 +109,21 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use("/", domainProxy.router) app.router.use("/", domainProxy.router)
app.wsRouter.use("/", domainProxy.wsRouter.router) app.wsRouter.use("/", domainProxy.wsRouter.router)
app.router.all("/proxy/:port/:path(.*)?", async (req, res) => { app.router.all("/proxy/(:port)(/*)?", async (req, res) => {
await pathProxy.proxy(req, res) await pathProxy.proxy(req, res)
}) })
app.wsRouter.get("/proxy/:port/:path(.*)?", async (req) => { app.wsRouter.get("/proxy/(:port)(/*)?", async (req) => {
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest) await pathProxy.wsProxy(req as pluginapi.WebsocketRequest)
}) })
// These two routes pass through the path directly. // These two routes pass through the path directly.
// So the proxied app must be aware it is running // So the proxied app must be aware it is running
// under /absproxy/<someport>/ // under /absproxy/<someport>/
app.router.all("/absproxy/:port/:path(.*)?", async (req, res) => { app.router.all("/absproxy/(:port)(/*)?", async (req, res) => {
await pathProxy.proxy(req, res, { await pathProxy.proxy(req, res, {
passthroughPath: true, passthroughPath: true,
}) })
}) })
app.wsRouter.get("/absproxy/:port/:path(.*)?", async (req) => { app.wsRouter.get("/absproxy/(:port)(/*)?", async (req) => {
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest, { await pathProxy.wsProxy(req as pluginapi.WebsocketRequest, {
passthroughPath: true, passthroughPath: true,
}) })
@@ -170,10 +170,12 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use("/update", update.router) app.router.use("/update", update.router)
const vsServerRouteHandler = new CodeServerRouteWrapper()
// Note that the root route is replaced in Coder Enterprise by the plugin API. // Note that the root route is replaced in Coder Enterprise by the plugin API.
for (const routePrefix of ["/vscode", "/"]) { for (const routePrefix of ["/vscode", "/"]) {
app.router.use(routePrefix, vscode.router) app.router.use(routePrefix, vsServerRouteHandler.router)
app.wsRouter.use(routePrefix, vscode.wsRouter.router) app.wsRouter.use(routePrefix, vsServerRouteHandler.wsRouter)
} }
app.router.use(() => { app.router.use(() => {
@@ -186,6 +188,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
return () => { return () => {
heart.dispose() heart.dispose()
pluginApi?.dispose() pluginApi?.dispose()
vscode.dispose() vsServerRouteHandler.dispose()
} }
} }

View File

@@ -68,8 +68,8 @@ router.get("/", async (req, res) => {
res.send(await getRoot(req)) res.send(await getRoot(req))
}) })
router.post<{}, string, { password?: string; base?: string } | undefined, { to?: string }>("/", async (req, res) => { router.post<{}, string, { password: string; base?: string }, { to?: string }>("/", async (req, res) => {
const password = sanitizeString(req.body?.password) const password = sanitizeString(req.body.password)
const hashedPasswordFromArgs = req.args["hashed-password"] const hashedPasswordFromArgs = req.args["hashed-password"]
try { try {

View File

@@ -22,7 +22,7 @@ export async function proxy(
if (!(await authenticated(req))) { if (!(await authenticated(req))) {
// If visiting the root (/:port only) redirect to the login page. // If visiting the root (/:port only) redirect to the login page.
if (!req.params.path || req.params.path === "/") { if (!req.params[0] || req.params[0] === "/") {
const to = self(req) const to = self(req)
return redirect(req, res, "login", { return redirect(req, res, "login", {
to: to !== "/" ? to : undefined, to: to !== "/" ? to : undefined,

View File

@@ -14,190 +14,203 @@ import { SocketProxyProvider } from "../socket"
import { isFile, loadAMDModule } from "../util" import { isFile, loadAMDModule } from "../util"
import { Router as WsRouter } from "../wsRouter" import { Router as WsRouter } from "../wsRouter"
export const router = express.Router()
export const wsRouter = WsRouter()
/** /**
* The API of VS Code's web client server. code-server delegates requests to VS * This is the API of Code's web client server. code-server delegates requests
* Code here. * to Code here.
*
* @see ../../../lib/vscode/src/vs/server/node/server.main.ts:72
*/ */
export interface IVSCodeServerAPI { export interface IServerAPI {
handleRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> handleRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>
handleUpgrade(req: http.IncomingMessage, socket: net.Socket): void handleUpgrade(req: http.IncomingMessage, socket: net.Socket): void
handleServerError(err: Error): void handleServerError(err: Error): void
dispose(): void dispose(): void
} }
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72. // Types for ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
export type CreateServer = (address: string | net.AddressInfo | null, args: CodeArgs) => Promise<IVSCodeServerAPI> export type CreateServer = (address: string | net.AddressInfo | null, args: CodeArgs) => Promise<IServerAPI>
// The VS Code server is dynamically loaded in when a request is made to this export class CodeServerRouteWrapper {
// router by `ensureCodeServerLoaded`. /** Assigned in `ensureCodeServerLoaded` */
let vscodeServer: IVSCodeServerAPI | undefined private _codeServerMain!: IServerAPI
private _wsRouterWrapper = WsRouter()
private _socketProxyProvider = new SocketProxyProvider()
public router = express.Router()
private mintKeyPromise: Promise<Buffer> | undefined
/** public get wsRouter() {
* Ensure the VS Code server is loaded. return this._wsRouterWrapper.router
*/
export const ensureVSCodeLoaded = async (
req: express.Request,
_: express.Response,
next: express.NextFunction,
): Promise<void> => {
if (vscodeServer) {
return next()
}
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
const createVSServer = await loadAMDModule<CreateServer>("vs/server/node/server.main", "createServer")
try {
vscodeServer = await createVSServer(null, {
...(await toCodeArgs(req.args)),
"accept-server-license-terms": true,
// This seems to be used to make the connection token flags optional (when
// set to 1.63) but we have always included them.
compatibility: "1.64",
"without-connection-token": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)
if (isDevMode) {
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
}
return next(error)
}
return next()
}
router.get("/", ensureVSCodeLoaded, async (req, res, next) => {
const isAuthenticated = await authenticated(req)
const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace
// Ew means the workspace was closed so clear the last folder/workspace.
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew
if (!isAuthenticated) {
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})
} }
if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) { //#region Route Handlers
const settings = await req.settings.read()
const lastOpened = settings.query || {}
// This flag disables the last opened behavior
const IGNORE_LAST_OPENED = req.args["ignore-last-opened"]
const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace
const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0
const to = self(req)
let folder = undefined private manifest: express.Handler = async (req, res, next) => {
let workspace = undefined const appName = req.args["app-name"] || "code-server"
res.writeHead(200, { "Content-Type": "application/manifest+json" })
// Redirect to the last folder/workspace if nothing else is opened. return res.end(
if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) { replaceTemplates(
folder = lastOpened.folder req,
workspace = lastOpened.workspace JSON.stringify(
} else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) { {
const lastEntry = path.resolve(req.args._[req.args._.length - 1]) name: appName,
const entryIsFile = await isFile(lastEntry) short_name: appName,
const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace" start_url: ".",
display: "fullscreen",
display_override: ["window-controls-overlay"],
description: "Run Code on a remote server.",
icons: [192, 512].map((size) => ({
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
type: "image/png",
sizes: `${size}x${size}`,
})),
},
null,
2,
),
),
)
}
if (IS_WORKSPACE_FILE) { private mintKey: express.Handler = async (req, res, next) => {
workspace = lastEntry if (!this.mintKeyPromise) {
} else if (!entryIsFile) { this.mintKeyPromise = new Promise(async (resolve) => {
folder = lastEntry const keyPath = path.join(req.args["user-data-dir"], "serve-web-key-half")
} logger.debug(`Reading server web key half from ${keyPath}`)
} try {
resolve(await fs.readFile(keyPath))
if (folder || workspace) { return
return redirect(req, res, to, { } catch (error: any) {
folder, if (error.code !== "ENOENT") {
workspace, logError(logger, `read ${keyPath}`, error)
}
}
// VS Code wants 256 bits.
const key = crypto.randomBytes(32)
try {
await fs.writeFile(keyPath, key)
} catch (error: any) {
logError(logger, `write ${keyPath}`, error)
}
resolve(key)
}) })
} }
const key = await this.mintKeyPromise
res.end(key)
} }
// Store the query parameters so we can use them on the next load. This private $root: express.Handler = async (req, res, next) => {
// also allows users to create functionality around query parameters. const isAuthenticated = await authenticated(req)
await req.settings.write({ query: req.query }) const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace
// Ew means the workspace was closed so clear the last folder/workspace.
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew
next() if (!isAuthenticated) {
}) const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})
}
router.get("/manifest.json", async (req, res) => { if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) {
const appName = req.args["app-name"] || "code-server" const settings = await req.settings.read()
res.writeHead(200, { "Content-Type": "application/manifest+json" }) const lastOpened = settings.query || {}
// This flag disables the last opened behavior
const IGNORE_LAST_OPENED = req.args["ignore-last-opened"]
const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace
const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0
const to = self(req)
return res.end( let folder = undefined
replaceTemplates( let workspace = undefined
req,
JSON.stringify(
{
name: appName,
short_name: appName,
start_url: ".",
display: "fullscreen",
display_override: ["window-controls-overlay"],
description: "Run Code on a remote server.",
icons: [192, 512].map((size) => ({
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
type: "image/png",
sizes: `${size}x${size}`,
})),
},
null,
2,
),
),
)
})
let mintKeyPromise: Promise<Buffer> | undefined // Redirect to the last folder/workspace if nothing else is opened.
router.post("/mint-key", async (req, res) => { if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) {
if (!mintKeyPromise) { folder = lastOpened.folder
mintKeyPromise = new Promise(async (resolve) => { workspace = lastOpened.workspace
const keyPath = path.join(req.args["user-data-dir"], "serve-web-key-half") } else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) {
logger.debug(`Reading server web key half from ${keyPath}`) const lastEntry = path.resolve(req.args._[req.args._.length - 1])
try { const entryIsFile = await isFile(lastEntry)
resolve(await fs.readFile(keyPath)) const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace"
return
} catch (error: any) { if (IS_WORKSPACE_FILE) {
if (error.code !== "ENOENT") { workspace = lastEntry
logError(logger, `read ${keyPath}`, error) } else if (!entryIsFile) {
folder = lastEntry
} }
} }
// VS Code wants 256 bits.
const key = crypto.randomBytes(32) if (folder || workspace) {
try { return redirect(req, res, to, {
await fs.writeFile(keyPath, key) folder,
} catch (error: any) { workspace,
logError(logger, `write ${keyPath}`, error) })
} }
resolve(key) }
})
// Store the query parameters so we can use them on the next load. This
// also allows users to create functionality around query parameters.
await req.settings.write({ query: req.query })
next()
} }
const key = await mintKeyPromise
res.end(key)
})
router.all(/.*/, ensureAuthenticated, ensureVSCodeLoaded, async (req, res) => { private $proxyRequest: express.Handler = async (req, res, next) => {
vscodeServer!.handleRequest(req, res) this._codeServerMain.handleRequest(req, res)
}) }
const socketProxyProvider = new SocketProxyProvider() private $proxyWebsocket = async (req: WebsocketRequest) => {
wsRouter.ws(/.*/, ensureOrigin, ensureAuthenticated, ensureVSCodeLoaded, async (req: WebsocketRequest) => { const wrappedSocket = await this._socketProxyProvider.createProxy(req.ws)
const wrappedSocket = await socketProxyProvider.createProxy(req.ws) // This should actually accept a duplex stream but it seems Code has not
// This should actually accept a duplex stream but it seems Code has not // been updated to match the Node 16 types so cast for now. There does not
// been updated to match the Node 16 types so cast for now. There does not // appear to be any code specific to sockets so this should be fine.
// appear to be any code specific to sockets so this should be fine. this._codeServerMain.handleUpgrade(req, wrappedSocket as net.Socket)
vscodeServer!.handleUpgrade(req, wrappedSocket as net.Socket)
req.ws.resume() req.ws.resume()
}) }
export function dispose() { //#endregion
vscodeServer?.dispose()
socketProxyProvider.stop() /**
* Fetches a code server instance asynchronously to avoid an initial memory overhead.
*/
private ensureCodeServerLoaded: express.Handler = async (req, _res, next) => {
if (this._codeServerMain) {
// Already loaded...
return next()
}
// Create the server...
const { args } = req
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
const createVSServer = await loadAMDModule<CreateServer>("vs/server/node/server.main", "createServer")
try {
this._codeServerMain = await createVSServer(null, {
...(await toCodeArgs(args)),
"without-connection-token": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)
if (isDevMode) {
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
}
return next(error)
}
return next()
}
constructor() {
this.router.get("/", this.ensureCodeServerLoaded, this.$root)
this.router.get("/manifest.json", this.manifest)
this.router.post("/mint-key", this.mintKey)
this.router.all("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyRequest)
this._wsRouterWrapper.ws("*", ensureOrigin, ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket)
}
dispose() {
this._codeServerMain?.dispose()
this._socketProxyProvider.stop()
}
} }

View File

@@ -105,7 +105,6 @@ export class UpdateProvider {
logger.debug("Making request", field("uri", uri)) logger.debug("Making request", field("uri", uri))
const isHttps = uri.startsWith("https") const isHttps = uri.startsWith("https")
const agent = new ProxyAgent({ const agent = new ProxyAgent({
keepAlive: true,
getProxyForUrl: () => httpProxyUri || "", getProxyForUrl: () => httpProxyUri || "",
}) })
const httpx = isHttps ? https : http const httpx = isHttps ? https : http

View File

@@ -20,11 +20,11 @@ export interface EditorSessionEntry {
} }
interface DeleteSessionRequest { interface DeleteSessionRequest {
socketPath?: string socketPath: string
} }
interface AddSessionRequest { interface AddSessionRequest {
entry?: EditorSessionEntry entry: EditorSessionEntry
} }
interface GetSessionResponse { interface GetSessionResponse {
@@ -40,42 +40,37 @@ export async function makeEditorSessionManagerServer(
// eslint-disable-next-line import/no-named-as-default-member // eslint-disable-next-line import/no-named-as-default-member
router.use(express.json()) router.use(express.json())
router.get<{}, GetSessionResponse | string | unknown, undefined, { filePath?: string }>( router.get("/session", async (req, res) => {
"/session", const filePath = req.query.filePath as string
async (req, res) => { if (!filePath) {
const filePath = req.query.filePath res.status(HttpCode.BadRequest).send("filePath is required")
if (!filePath) {
res.status(HttpCode.BadRequest).send("filePath is required")
return
}
try {
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
}
},
)
router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => {
const entry = req.body?.entry
if (!entry) {
res.status(400).send("entry is required")
return return
} }
editorSessionManager.addSession(entry) try {
res.status(200).send("session added") const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
}
}) })
router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => { router.post("/add-session", async (req, res) => {
const socketPath = req.body?.socketPath const request = req.body as AddSessionRequest
if (!socketPath) { if (!request.entry) {
res.status(400).send("socketPath is required") res.status(400).send("entry is required")
return
} }
editorSessionManager.deleteSession(socketPath) editorSessionManager.addSession(request.entry)
res.status(200).send("session deleted") res.status(200).send()
})
router.post("/delete-session", async (req, res) => {
const request = req.body as DeleteSessionRequest
if (!request.socketPath) {
res.status(400).send("socketPath is required")
}
editorSessionManager.deleteSession(request.socketPath)
res.status(200).send()
}) })
const server = http.createServer(router) const server = http.createServer(router)

View File

@@ -13,10 +13,9 @@ describe("--install-extension", () => {
}) })
it("should use EXTENSIONS_GALLERY when set", async () => { it("should use EXTENSIONS_GALLERY when set", async () => {
const extName = "author.extension" const extName = "author.extension"
await expect( const { stderr } = await runCodeServerCommand([...setupFlags, "--install-extension", extName], {
runCodeServerCommand([...setupFlags, "--install-extension", extName], { EXTENSIONS_GALLERY: "{}",
EXTENSIONS_GALLERY: "{}", })
}), expect(stderr).toMatch("No extension gallery service configured")
).rejects.toThrow("No extension gallery service configured")
}) })
}) })

View File

@@ -912,6 +912,8 @@ cert: false`)
describe("toCodeArgs", () => { describe("toCodeArgs", () => {
const vscodeDefaults = { const vscodeDefaults = {
...defaults, ...defaults,
"accept-server-license-terms": true,
compatibility: "1.64",
help: false, help: false,
port: "8080", port: "8080",
version: false, version: false,

View File

@@ -199,7 +199,7 @@ describe("proxy", () => {
}) })
it("should proxy non-ASCII", async () => { it("should proxy non-ASCII", async () => {
e.get(/.*/, (req, res) => { e.get("*", (req, res) => {
res.json("ほげ") res.json("ほげ")
}) })
codeServer = await integration.setup(["--auth=none"], "") codeServer = await integration.setup(["--auth=none"], "")
@@ -211,7 +211,7 @@ describe("proxy", () => {
it("should not double-encode query variables", async () => { it("should not double-encode query variables", async () => {
const spy = jest.fn() const spy = jest.fn()
e.get(/.*/, (req, res) => { e.get("*", (req, res) => {
spy([req.originalUrl, req.query]) spy([req.originalUrl, req.query])
res.end() res.end()
}) })

View File

@@ -68,10 +68,13 @@ describe("login", () => {
} }
}) })
it("should return 'Missing password' without body", async () => { it("should return HTML with 'Missing password' message", async () => {
const resp = await codeServer().fetch("/login", { method: "POST" }) const resp = await codeServer().fetch("/login", { method: "POST" })
const htmlContent = await resp.text()
expect(resp.status).toBe(200) expect(resp.status).toBe(200)
const htmlContent = await resp.text()
expect(htmlContent).toContain("Missing password") expect(htmlContent).toContain("Missing password")
}) })

View File

@@ -1906,9 +1906,9 @@ inherits@2, inherits@^2.0.3:
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ip@^1.1.5: ip@^1.1.5:
version "1.1.9" version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ== integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
is-core-module@^2.8.0: is-core-module@^2.8.0:
version "2.8.1" version "2.8.1"
@@ -2626,11 +2626,6 @@ minipass@^3.0.0:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
minipass@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
minizlib@^2.1.1: minizlib@^2.1.1:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
@@ -3298,13 +3293,13 @@ symbol-tree@^3.2.4:
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
tar@^6.1.11, tar@^6.1.9: tar@^6.1.11, tar@^6.1.9:
version "6.2.1" version "6.1.11"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
dependencies: dependencies:
chownr "^2.0.0" chownr "^2.0.0"
fs-minipass "^2.0.0" fs-minipass "^2.0.0"
minipass "^5.0.0" minipass "^3.0.0"
minizlib "^2.1.1" minizlib "^2.1.1"
mkdirp "^1.0.3" mkdirp "^1.0.3"
yallist "^4.0.0" yallist "^4.0.0"

708
yarn.lock

File diff suppressed because it is too large Load Diff