Compare commits

...

22 Commits

Author SHA1 Message Date
Asher
93c1f4f10c Update macOS runner
Seems macos-13 is being deprecated.
2025-11-18 13:25:39 -09:00
Olivier Benz
339c3926c2 Update Code to 1.106.0 (#7569) 2025-11-18 11:21:41 -09:00
dependabot[bot]
897b5f13bc chore: bump playwright and @playwright/test in /test (#7534) 2025-10-28 16:14:42 -08:00
SuitDeer
282f74d9f5 Update Node.js version in Android docs from 18 to 22 (#7542) 2025-10-28 16:14:17 -08:00
dependabot[bot]
7a2a5eb055 chore: bump eslint from 9.32.0 to 9.36.0 (#7513) 2025-10-28 16:13:34 -08:00
dependabot[bot]
af397f71e2 chore: bump globals from 16.1.0 to 16.4.0 (#7511) 2025-10-28 16:13:15 -08:00
dependabot[bot]
9d89b17fd7 chore: bump express and @types/express (#7510) 2025-10-28 16:12:45 -08:00
dependabot[bot]
35e7b09a85 chore: bump actions/checkout from 4 to 5 (#7508) 2025-10-28 16:12:00 -08:00
dependabot[bot]
7beb05d04f chore: bump aquasecurity/trivy-action from 0.32.0 to 0.33.1 (#7507) 2025-10-28 16:11:42 -08:00
dependabot[bot]
add51d5c5b chore: bump actions/download-artifact from 4 to 5 (#7506) 2025-10-28 16:11:23 -08:00
Andrew Baldwin
db8a41bce1 Add idle timeout (#7539) 2025-10-28 16:10:56 -08:00
Olivier Benz
811ec6c1d6 Update Code to 1.105.1 (#7531) 2025-10-17 14:32:32 -08:00
Olivier Benz
30321abfcd Update Code to 1.105.0 (#7523) 2025-10-14 13:26:57 -08:00
Olivier Benz
cd40509fbb Update Code to 1.104.3 (#7515) 2025-10-03 10:48:01 -08:00
Asher
9fd98d58e7 Release v4.104.1 and v4.104.2 2025-10-01 14:15:07 -08:00
Olivier Benz
b0992ddb3e Update Code to 1.104.2 (#7503) 2025-09-26 10:36:08 -08:00
Olivier Benz
af19dedfa9 Update Code to 1.104.1 (#7495) 2025-09-19 10:01:30 -08:00
Asher
d1066af558 Release v4.104.0 2025-09-15 14:36:47 -08:00
Olivier Benz
ba774d989b Update Code to 1.104.0 (#7488) 2025-09-12 12:41:54 -08:00
Jinvien
1a7b770f5b Fix installing extensions from the Open VSX marketplace (#7479)
Open VSX uses a non-standard format for the `/latest` URL which must be added to the gallery config.
2025-09-11 14:26:49 -08:00
Anthony
626145cf66 Allow custom annotation to deployment (#7481) 2025-09-11 14:24:57 -08:00
Asher
b59a4f7366 Release v4.103.1 and v4.103.2 2025-08-28 11:55:58 -08:00
40 changed files with 454 additions and 399 deletions

View File

@@ -32,7 +32,7 @@ jobs:
helm: ${{ steps.filter.outputs.helm }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Check changed files
uses: dorny/paths-filter@v3
id: filter
@@ -64,7 +64,7 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
@@ -82,7 +82,7 @@ jobs:
needs: changes
if: needs.changes.outputs.docs == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
@@ -100,7 +100,7 @@ jobs:
needs: changes
if: needs.changes.outputs.helm == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -114,7 +114,7 @@ jobs:
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
@@ -132,7 +132,7 @@ jobs:
if: needs.changes.outputs.ci == 'true'
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.1
@@ -146,7 +146,7 @@ jobs:
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
@@ -169,7 +169,7 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
DISABLE_V8_COMPILE_CACHE: 1
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true
- run: sudo apt update && sudo apt install -y libkrb5-dev
@@ -231,7 +231,7 @@ jobs:
needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: actions/setup-node@v4
with:
@@ -241,7 +241,7 @@ jobs:
package-lock.json
test/package-lock.json
- run: SKIP_SUBMODULE_DEPS=1 npm ci
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v5
with:
name: npm-package
- run: tar -xzf package.tar.gz
@@ -265,7 +265,7 @@ jobs:
needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: actions/setup-node@v4
with:
@@ -275,7 +275,7 @@ jobs:
package-lock.json
test/package-lock.json
- run: SKIP_SUBMODULE_DEPS=1 npm ci
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v5
with:
name: npm-package
- run: tar -xzf package.tar.gz

View File

@@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install code-server
run: ./install.sh
@@ -44,7 +44,7 @@ jobs:
container: "alpine:3.17"
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install curl
run: apk add curl
@@ -67,7 +67,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install code-server
run: ./install.sh

View File

@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code-server
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v4
@@ -65,7 +65,7 @@ jobs:
uses: Homebrew/actions/setup-homebrew@master
- name: Checkout code-server
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Configure git
run: |
@@ -94,13 +94,13 @@ jobs:
steps:
# We need to checkout code-server so we can get the version
- name: Checkout code-server
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
path: "./code-server"
- name: Checkout code-server-aur repo
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: "cdrci/code-server-aur"
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
@@ -148,7 +148,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code-server
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

View File

@@ -60,7 +60,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v4
@@ -94,7 +94,7 @@ jobs:
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Download npm package
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: npm-release-package
@@ -126,7 +126,7 @@ jobs:
package-macos-amd64:
name: x86-64 macOS build
runs-on: macos-13
runs-on: macos-15-intel
timeout-minutes: 15
needs: npm-version
env:
@@ -134,7 +134,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v4
@@ -160,7 +160,7 @@ jobs:
- run: brew install python-setuptools
- name: Download npm package
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: npm-release-package
@@ -195,7 +195,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v4
@@ -221,7 +221,7 @@ jobs:
- run: brew install python-setuptools
- name: Download npm package
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: npm-release-package
@@ -253,7 +253,7 @@ jobs:
needs: npm-version
steps:
- name: Download npm package
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: npm-release-package

View File

@@ -41,7 +41,7 @@ jobs:
container: "alpine:3.17"
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install test utilities
run: apk add bats checkbashisms
@@ -58,7 +58,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install lint utilities
run: sudo apt install shellcheck

View File

@@ -25,7 +25,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -46,12 +46,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
with:
scan-type: "fs"
scan-ref: "."
@@ -76,7 +76,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -48,10 +48,10 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@dc5a429b52fcf669ce959baa2c2dd26090d2a6c4
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
with:
image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true

View File

@@ -1 +1 @@
22.17.0
22.20.0

View File

@@ -22,6 +22,51 @@ Code v99.99.999
## Unreleased
## [4.104.2](https://github.com/coder/code-server/releases/tag/v4.104.2) - 2025-09-26
Code v1.104.2
### Changed
- Update to Code 1.104.2.
## [4.104.1](https://github.com/coder/code-server/releases/tag/v4.104.1) - 2025-09-19
Code v1.104.1
### Changed
- Update to Code 1.104.1.
## [4.104.0](https://github.com/coder/code-server/releases/tag/v4.104.0) - 2025-09-15
Code v1.104.0
### Fixed
- Fix "extension not found" errors from Open VSX when trying to install the
latest version of an extension.
### Changed
- Update to Code 1.104.0.
## [4.103.2](https://github.com/coder/code-server/releases/tag/v4.103.2) - 2025-08-25
Code v1.103.2
### Changed
- Update to Code 1.103.2.
## [4.103.1](https://github.com/coder/code-server/releases/tag/v4.103.1) - 2025-08-15
Code v1.103.1
### Changed
- Update to Code 1.103.1.
## [4.103.0](https://github.com/coder/code-server/releases/tag/v4.103.0) - 2025-08-12
Code v1.103.0

View File

@@ -15,9 +15,9 @@ type: application
# 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.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.30.0
version: 3.31.2
# 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
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.103.0
appVersion: 4.104.2

View File

@@ -7,6 +7,9 @@ metadata:
helm.sh/chart: {{ include "code-server.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.annotations }}
annotations: {{- toYaml .Values.annotations | nindent 4 }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount | default 1 }}
strategy:

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.103.0'
tag: '4.104.2'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a
@@ -31,6 +31,9 @@ serviceAccount:
# If not set and create is true, a name is generated using the fullname template
name: ""
# Specifies annotations for deployment
annotations: {}
podAnnotations: {}
podSecurityContext: {}

View File

@@ -322,12 +322,8 @@ As long as there is an active browser connection, code-server touches
`~/.local/share/code-server/heartbeat` once a minute.
If you want to shutdown code-server if there hasn't been an active connection
after a predetermined amount of time, you can do so by checking continuously for
the last modified time on the heartbeat file. If it is older than X minutes (or
whatever amount of time you'd like), you can kill code-server.
Eventually, [#1636](https://github.com/coder/code-server/issues/1636) will make
this process better.
after a predetermined amount of time, you can use the --idle-timeout-seconds flag
or set an `CODE_SERVER_IDLE_TIMEOUT_SECONDS` environment variable.
## How do I change the password?

View File

@@ -14,8 +14,8 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
7. Install and use Node.js 22:
```shell
nvm install 18
nvm use 18
nvm install 22
nvm use 22
```
8. Install code-server globally on device with: `npm install --global code-server`

320
package-lock.json generated
View File

@@ -128,9 +128,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -190,9 +190,9 @@
}
},
"node_modules/@eslint/config-helpers": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
"integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
"integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -200,9 +200,9 @@
}
},
"node_modules/@eslint/core": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
"integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
"integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -250,9 +250,9 @@
}
},
"node_modules/@eslint/js": {
"version": "9.32.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz",
"integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==",
"version": "9.36.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz",
"integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -273,13 +273,13 @@
}
},
"node_modules/@eslint/plugin-kit": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz",
"integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==",
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
"integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.15.1",
"@eslint/core": "^0.15.2",
"levn": "^0.4.1"
},
"engines": {
@@ -610,15 +610,14 @@
"license": "MIT"
},
"node_modules/@types/express": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz",
"integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
"integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^5.0.0",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
@@ -1640,18 +1639,18 @@
}
},
"node_modules/body-parser": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz",
"integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.0",
"http-errors": "^2.0.0",
"iconv-lite": "^0.5.2",
"iconv-lite": "^0.6.3",
"on-finished": "^2.4.1",
"qs": "6.14.0",
"qs": "^6.14.0",
"raw-body": "^3.0.0",
"type-is": "^2.0.0"
},
@@ -2150,16 +2149,6 @@
"node": ">= 0.8"
}
},
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"license": "MIT",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/detect-libc": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
@@ -2490,20 +2479,20 @@
}
},
"node_modules/eslint": {
"version": "9.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz",
"integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==",
"version": "9.36.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz",
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.21.0",
"@eslint/config-helpers": "^0.3.0",
"@eslint/core": "^0.15.0",
"@eslint/config-helpers": "^0.3.1",
"@eslint/core": "^0.15.2",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.32.0",
"@eslint/plugin-kit": "^0.3.4",
"@eslint/js": "9.36.0",
"@eslint/plugin-kit": "^0.3.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -2903,55 +2892,45 @@
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
},
"node_modules/express": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz",
"integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.0.1",
"body-parser": "^2.2.0",
"content-disposition": "^1.0.0",
"content-type": "~1.0.4",
"cookie": "0.7.1",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "4.3.6",
"depd": "2.0.0",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "^2.0.0",
"fresh": "2.0.0",
"http-errors": "2.0.0",
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"finalhandler": "^2.1.0",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"merge-descriptors": "^2.0.0",
"methods": "~1.1.2",
"mime-types": "^3.0.0",
"on-finished": "2.4.1",
"once": "1.4.0",
"parseurl": "~1.3.3",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"range-parser": "~1.2.1",
"router": "^2.0.0",
"safe-buffer": "5.2.1",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
"serve-static": "^2.1.0",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "^2.0.0",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
"serve-static": "^2.2.0",
"statuses": "^2.0.1",
"type-is": "^2.0.1",
"vary": "^1.1.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/express/node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/express/node_modules/cookie-signature": {
@@ -2963,44 +2942,6 @@
"node": ">=6.6.0"
}
},
"node_modules/express/node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/express/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/express/node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -3416,9 +3357,9 @@
}
},
"node_modules/globals": {
"version": "16.1.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz",
"integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==",
"version": "16.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
"integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3669,12 +3610,12 @@
}
},
"node_modules/iconv-lite": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz",
"integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
@@ -4480,15 +4421,6 @@
"node": ">= 8"
}
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/micromark": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
@@ -4630,20 +4562,21 @@
}
},
"node_modules/mime-db": {
"version": "1.53.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz",
"integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==",
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz",
"integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.53.0"
"mime-db": "^1.54.0"
},
"engines": {
"node": ">= 0.6"
@@ -5120,12 +5053,13 @@
"dev": true
},
"node_modules/path-to-regexp": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
"license": "MIT",
"engines": {
"node": ">=16"
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/pem": {
@@ -5334,30 +5268,34 @@
}
},
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz",
"integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"iconv-lite": "0.7.0",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
"node": ">= 0.10"
}
},
"node_modules/raw-body/node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/readable-stream": {
@@ -5535,11 +5473,13 @@
}
},
"node_modules/router": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz",
"integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"depd": "^2.0.0",
"is-promise": "^4.0.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.0.0"
@@ -5653,19 +5593,18 @@
}
},
"node_modules/send": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz",
"integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.5",
"destroy": "^1.2.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"fresh": "^0.5.2",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"mime-types": "^2.1.35",
"mime-types": "^3.0.1",
"ms": "^2.1.3",
"on-finished": "^2.4.1",
"range-parser": "^1.2.1",
@@ -5675,46 +5614,16 @@
"node": ">= 18"
}
},
"node_modules/send/node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/send/node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/send/node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/serve-static": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz",
"integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"parseurl": "^1.3.3",
"send": "^1.0.0"
"send": "^1.2.0"
},
"engines": {
"node": ">= 18"
@@ -6307,9 +6216,9 @@
}
},
"node_modules/type-is": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz",
"integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
"license": "MIT",
"dependencies": {
"content-type": "^1.0.5",
@@ -6621,15 +6530,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",

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/lib/vscode/src/vs/base/common/network.ts
@@ -226,7 +226,9 @@ class RemoteAuthoritiesImpl {
@@ -237,7 +237,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -99,14 +99,14 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactor
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
@@ -281,6 +281,7 @@ export class BrowserSocketFactory implem
@@ -282,6 +282,7 @@ export class BrowserSocketFactory implem
connect({ host, port }: WebSocketRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
return new Promise<ISocket>((resolve, reject) => {
const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws');
+ path = (mainWindow.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError(reject);
socket.onOpen(() => {
const disposables = new DisposableStore();
disposables.add(socket.onError(reject));
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -241,7 +241,7 @@ 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
@@ -57,6 +57,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -65,6 +65,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
@@ -253,7 +253,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
@@ -338,7 +338,8 @@ class LocalStorageURLCallbackProvider ex
@@ -339,7 +339,8 @@ class LocalStorageURLCallbackProvider ex
this.startListening();
}
@@ -263,7 +263,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
}
private startListening(): void {
@@ -583,17 +584,6 @@ class WorkspaceProvider implements IWork
@@ -584,17 +585,6 @@ class WorkspaceProvider implements IWork
}
}
@@ -281,7 +281,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
(function () {
// Find config by checking for DOM
@@ -602,8 +592,8 @@ function readCookie(name: string): strin
@@ -604,8 +594,8 @@ function readCookie(name: string): strin
if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element');
}

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/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -106,10 +106,14 @@ class RemoteTerminalBackend extends Base
@@ -107,10 +107,14 @@ class RemoteTerminalBackend extends Base
}
const reqId = e.reqId;
const commandId = e.commandId;

View File

@@ -65,7 +65,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/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -97,7 +97,7 @@ class RemoteTerminalBackend extends Base
@@ -98,7 +98,7 @@ class RemoteTerminalBackend extends Base
}
});
@@ -78,7 +78,7 @@ 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
@@ -135,6 +135,7 @@ export interface NativeParsedArgs {
@@ -137,6 +137,7 @@ export interface NativeParsedArgs {
'disable-chromium-sandbox'?: boolean;
sandbox?: boolean;
'enable-coi'?: boolean;
@@ -90,7 +90,7 @@ 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
@@ -104,6 +104,7 @@ export const OPTIONS: OptionDescriptions
@@ -105,6 +105,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.") },

View File

@@ -11,14 +11,14 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -12,7 +12,7 @@ import * as path from '../../base/common
import { IURITransformer } from '../../base/common/uriIpc.js';
import { getMachineId, getSqmMachineId, getdevDeviceId } from '../../base/node/id.js';
import { getMachineId, getSqmMachineId, getDevDeviceId } from '../../base/node/id.js';
import { Promises } from '../../base/node/pfs.js';
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
+import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
import { ConfigurationService } from '../../platform/configuration/common/configurationService.js';
@@ -269,6 +269,9 @@ export async function setupServerService
@@ -272,6 +272,9 @@ export async function setupServerService
socketServer.registerChannel('mcpManagement', new McpManagementChannel(mcpManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)));
@@ -339,7 +339,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
@@ -54,7 +54,7 @@ import './services/dialogs/browser/fileD
@@ -55,7 +55,7 @@ import './services/dialogs/browser/fileD
import './services/host/browser/browserHostService.js';
import './services/lifecycle/browser/lifecycleService.js';
import './services/clipboard/browser/clipboardService.js';

View File

@@ -125,13 +125,12 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,11 +7,11 @@ import { Event } from '../../base/common
import { Disposable, DisposableStore, MutableDisposable } from '../../base/common/lifecycle.js';
@@ -6,10 +6,10 @@
import { Disposable } from '../../base/common/lifecycle.js';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext } from '../common/contextkeys.js';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
import { IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext } from '../common/contextkeys.js';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
-import { IWorkbenchEnvironmentService } from '../services/environment/common/environmentService.js';
@@ -139,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from '../../platform/workspace/common/workspace.js';
import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js';
import { getRemoteName } from '../../platform/remote/common/remoteHosts.js';
@@ -71,7 +71,7 @@ export class WorkbenchContextKeysHandler
@@ -69,7 +69,7 @@ export class WorkbenchContextKeysHandler
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -148,7 +147,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@IProductService private readonly productService: IProductService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IEditorService private readonly editorService: IEditorService,
@@ -200,6 +200,10 @@ export class WorkbenchContextKeysHandler
@@ -199,6 +199,10 @@ export class WorkbenchContextKeysHandler
this.auxiliaryBarMaximizedContext = AuxiliaryBarMaximizedContext.bindTo(this.contextKeyService);
this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized());
@@ -208,9 +207,9 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -37,6 +37,9 @@ export const HasWebFileSystemAccess = ne
@@ -39,6 +39,9 @@ export const EmbedderIdentifierContext =
export const EmbedderIdentifierContext = new RawContextKey<string | undefined>('embedderIdentifier', undefined, localize('embedderIdentifier', 'The identifier of the embedder according to the product service, if one is defined'));
export const InAutomationContext = new RawContextKey<boolean>('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test"));
+export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
@@ -240,8 +239,8 @@ Index: code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFi
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IPathService protected readonly pathService: IPathService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@@ -310,20 +310,22 @@ export class SimpleFileDialog extends Di
this.filePickBox.ignoreFocusOut = true;
@@ -311,20 +311,22 @@ export class SimpleFileDialog extends Di
this.filePickBox.placeholder = nls.localize('remoteFileDialog.placeholder', "Folder path");
this.filePickBox.ok = true;
this.filePickBox.okLabel = typeof this.options.openLabel === 'string' ? this.options.openLabel : this.options.openLabel?.withoutMnemonic;
- if ((this.scheme !== Schemas.file) && this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) {
@@ -289,7 +288,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
import { WorkbenchCompressibleAsyncDataTree } from '../../../../../platform/list/browser/listService.js';
import { ISearchService, QueryType, getExcludes, ISearchConfiguration, ISearchComplete, IFileQuery } from '../../../../services/search/common/search.js';
import { CancellationToken } from '../../../../../base/common/cancellation.js';
@@ -1601,7 +1602,8 @@ export class FileDragAndDrop implements
@@ -1594,7 +1595,8 @@ export class FileDragAndDrop implements
@IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
@@ -299,7 +298,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
) {
const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => {
if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) {
@@ -1826,15 +1828,17 @@ export class FileDragAndDrop implements
@@ -1819,15 +1821,17 @@ export class FileDragAndDrop implements
// External file DND (Import/Upload file)
if (data instanceof NativeDragAndDropData) {

View File

@@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
import { renderFormattedText } from '../../../../base/browser/formattedTextRenderer.js';
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
import { Button } from '../../../../base/browser/ui/button/button.js';
@@ -54,7 +54,7 @@ import { IRecentFolder, IRecentWorkspace
@@ -53,7 +53,7 @@ import { IRecentFolder, IRecentWorkspace
import { OpenRecentAction } from '../../../browser/actions/windowActions.js';
import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from '../../../browser/actions/workspaceActions.js';
import { EditorPane } from '../../../browser/parts/editor/editorPane.js';
@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
import { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js';
import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js';
import './gettingStartedColors.js';
@@ -876,6 +876,72 @@ export class GettingStartedPage extends
@@ -902,6 +902,72 @@ export class GettingStartedPage extends
$('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 rightColumn = $('.categories-column.categories-column-right', {},);
@@ -911,6 +977,9 @@ export class GettingStartedPage extends
@@ -937,6 +1003,9 @@ export class GettingStartedPage extends
recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
}
@@ -213,16 +213,16 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,7 +7,7 @@ import { Event } from '../../base/common
import { Disposable, DisposableStore, MutableDisposable } from '../../base/common/lifecycle.js';
@@ -6,7 +6,7 @@
import { Disposable } from '../../base/common/lifecycle.js';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
import { IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
@@ -203,6 +203,7 @@ export class WorkbenchContextKeysHandler
import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService.js';
@@ -202,6 +202,7 @@ export class WorkbenchContextKeysHandler
// code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
@@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -39,6 +39,7 @@ export const EmbedderIdentifierContext =
@@ -41,6 +41,7 @@ export const InAutomationContext = new R
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);

View File

@@ -109,24 +109,6 @@ Index: code-server/lib/vscode/src/vs/base/common/processes.ts
];
const envKeys = Object.keys(env);
envKeys
Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
@@ -78,8 +78,11 @@ export class BrowserDialogHandler extend
async about(): Promise<void> {
const detailString = (useAgo: boolean): string => {
- return localize('aboutDetail',
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
+ return localize('aboutCodeServerDetail',
+ "code-server: {0}",
+ this.productService.codeServerVersion ? `v${this.productService.codeServerVersion}` : 'Unknown'
+ ) + '\n' + localize('aboutDetail',
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
this.productService.version || 'Unknown',
this.productService.commit || 'Unknown',
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
===================================================================
--- /dev/null
@@ -204,7 +186,7 @@ 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
@@ -56,6 +56,8 @@ export type ExtensionVirtualWorkspaceSup
@@ -64,6 +64,8 @@ export type ExtensionVirtualWorkspaceSup
};
export interface IProductConfiguration {
@@ -281,9 +263,9 @@ Index: code-server/lib/vscode/src/server-main.ts
===================================================================
--- code-server.orig/lib/vscode/src/server-main.ts
+++ code-server/lib/vscode/src/server-main.ts
@@ -25,6 +25,9 @@ const __dirname = path.dirname(fileURLTo
@@ -22,6 +22,9 @@ import { IServerAPI } from './vs/server/
perf.mark('code/server/start');
(globalThis as any).vscodeServerStartTime = performance.now();
(globalThis as { vscodeServerStartTime?: number }).vscodeServerStartTime = performance.now();
+// This is not indented to make the diff less noisy. We need to move this out
+// of the top-level so it will not run immediately and we can control the start.
@@ -291,15 +273,15 @@ Index: code-server/lib/vscode/src/server-main.ts
// Do a quick parse to determine if a server or the cli needs to be started
const parsedArgs = minimist(process.argv.slice(2), {
boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'],
@@ -153,6 +156,7 @@ if (shouldSpawnCli) {
@@ -150,6 +153,7 @@ if (shouldSpawnCli) {
}
});
}
+}
function sanitizeStringArg(val: any): string | undefined {
function sanitizeStringArg(val: unknown): string | undefined {
if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array
@@ -286,3 +290,22 @@ function prompt(question: string): Promi
@@ -283,3 +287,22 @@ function prompt(question: string): Promi
});
});
}
@@ -310,7 +292,7 @@ Index: code-server/lib/vscode/src/server-main.ts
+ osLocale: 'en',
+ commit: product.commit,
+ userDataPath: '',
+ nlsMetadataPath: __dirname,
+ nlsMetadataPath: import.meta.dirname,
+ });
+ return loadCode(nlsConfiguration);
+}
@@ -322,3 +304,21 @@ Index: code-server/lib/vscode/src/server-main.ts
+if (!process.env.CODE_SERVER_PARENT_PID) {
+ start();
+}
Index: code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
+++ code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
@@ -45,8 +45,11 @@ export function createWorkbenchDialogOpt
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
const detailString = (useAgo: boolean): string => {
- return localize('aboutDetail',
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
+ return localize('aboutCodeServerDetail',
+ "code-server: {0}",
+ productService.codeServerVersion ? `v${productService.codeServerVersion}` : 'Unknown'
+ ) + '\n' + localize('aboutDetail',
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
productService.version || 'Unknown',
productService.commit || 'Unknown',
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',

View File

@@ -32,7 +32,7 @@ Index: 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
*/
readonly configurationDefaults?: Record<string, any>;
readonly configurationDefaults?: Record<string, unknown>;
+ /**
+ * Path to the user data directory.
@@ -66,7 +66,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/configuration/browser/co
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
@@ -148,8 +148,10 @@ export class WorkspaceService extends Di
@@ -147,8 +147,10 @@ export class WorkspaceService extends Di
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService, uriIdentityService, logService));
this._register(this.workspaceConfiguration.onDidUpdateConfiguration(fromCache => {
this.onWorkspaceConfigurationChanged(fromCache).then(() => {

View File

@@ -8,7 +8,7 @@ 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
@@ -59,6 +59,7 @@ export interface IProductConfiguration {
@@ -67,6 +67,7 @@ export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string
readonly updateEndpoint?: string

View File

@@ -19,7 +19,7 @@ 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
@@ -49,6 +49,16 @@ else if (globalThis._VSCODE_PRODUCT_JSON
@@ -49,6 +49,17 @@ else if (globalThis._VSCODE_PRODUCT_JSON
version: pkg.version
});
}
@@ -28,6 +28,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
+ extensionsGallery: env.EXTENSIONS_GALLERY ? JSON.parse(env.EXTENSIONS_GALLERY) : (product.extensionsGallery || {
+ serviceUrl: "https://open-vsx.org/vscode/gallery",
+ itemUrl: "https://open-vsx.org/vscode/item",
+ extensionUrlTemplate: "https://open-vsx.org/vscode/gallery/{publisher}/{name}/latest",
+ resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
+ controlUrl: "",
+ recommendationsUrl: "",

View File

@@ -30,7 +30,7 @@ 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
@@ -60,6 +60,7 @@ export interface IProductConfiguration {
@@ -68,6 +68,7 @@ export interface IProductConfiguration {
readonly rootEndpoint?: string
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
@@ -83,7 +83,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE
===================================================================
--- 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
@@ -291,7 +291,7 @@ export async function createTerminalEnvi
@@ -292,7 +292,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
@@ -104,7 +104,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
import type { IURLCallbackProvider } from '../../../workbench/services/url/browser/urlService.js';
import { create } from '../../../workbench/workbench.web.main.internal.js';
@@ -604,6 +605,39 @@ class WorkspaceProvider implements IWork
@@ -606,6 +607,39 @@ class WorkspaceProvider implements IWork
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),

View File

@@ -6,7 +6,7 @@ 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
@@ -61,6 +61,10 @@ export interface IProductConfiguration {
@@ -69,6 +69,10 @@ export interface IProductConfiguration {
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
readonly proxyEndpointTemplate?: string

View File

@@ -96,7 +96,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
import minimist from 'minimist';
import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net';
@@ -436,7 +437,28 @@ async function startExtensionHostProcess
@@ -451,7 +452,28 @@ async function startExtensionHostProcess
);
// rewrite onTerminate-function to be a proper shutdown

View File

@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
import { NullPolicyService } from '../../platform/policy/common/policy.js';
import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js';
import { LoggerService } from '../../platform/log/node/loggerService.js';
@@ -164,11 +166,23 @@ export async function setupServerService
@@ -166,11 +168,23 @@ export async function setupServerService
const requestService = new RequestService('remote', configurationService, environmentService, logService);
services.set(IRequestService, requestService);
@@ -147,7 +147,7 @@ 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
@@ -65,6 +65,7 @@ export interface IProductConfiguration {
@@ -73,6 +73,7 @@ export interface IProductConfiguration {
readonly path: string;
readonly scope: string;
}
@@ -159,7 +159,7 @@ 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
@@ -57,7 +57,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
@@ -58,7 +58,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
controlUrl: "",
recommendationsUrl: "",

View File

@@ -93,7 +93,7 @@ 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
@@ -58,6 +58,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -66,6 +66,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string

View File

@@ -70,12 +70,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-qzQMf4WjRXHohkk4Hg1T0LJIElTDtjITLXbR/RuGA/Q=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-q8xbX8bFRtUAF+eVy0H2EWJWeyp3LsLyd7qwg1qndEg=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- content="default-src 'none'; script-src 'sha256-ZcIhtIuU4M9PbKfs7w/CLqHimFJRK8L7mYTXOfiUv0I=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-dVbEBqfV68sWYG05nAX+55pv4dls0VnI6ZDMMV/0GYQ=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -238,7 +238,7 @@
@@ -256,7 +256,7 @@
}
const swPath = encodeURI(`service-worker.js?v=${expectedWorkerVersion}&vscode-resource-base-authority=${searchParams.get('vscode-resource-base-authority')}&remoteAuthority=${searchParams.get('remoteAuthority') ?? ''}`);
@@ -84,7 +84,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
.then(async registration => {
/**
* @param {MessageEvent} event
@@ -351,6 +351,12 @@
@@ -370,6 +370,12 @@
const hostname = location.hostname;

View File

@@ -94,6 +94,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"welcome-text"?: string
"abs-proxy-base-path"?: string
i18n?: string
"idle-timeout-seconds"?: number
/* Positional arguments. */
_?: string[]
}
@@ -303,6 +304,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
path: true,
description: "Path to JSON file with custom translations. Merges with default strings and supports all i18n keys.",
},
"idle-timeout-seconds": {
type: "number",
description: "Timeout in seconds to wait before shutting down when idle.",
},
}
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
@@ -396,6 +401,10 @@ export const parse = (
throw new Error("--github-auth can only be set in the config file or passed in via $GITHUB_TOKEN")
}
if (key === "idle-timeout-seconds" && Number(value) <= 60) {
throw new Error("--idle-timeout-seconds must be greater than 60 seconds.")
}
const option = options[key]
if (option.type === "boolean") {
;(args[key] as boolean) = true
@@ -611,6 +620,16 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["github-auth"] = process.env.GITHUB_TOKEN
}
if (process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS) {
if (isNaN(Number(process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS))) {
logger.info("CODE_SERVER_IDLE_TIMEOUT_SECONDS must be a number")
}
if (Number(process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS) <= 60) {
throw new Error("--idle-timeout-seconds must be greater than 60 seconds.")
}
args["idle-timeout-seconds"] = Number(process.env.CODE_SERVER_IDLE_TIMEOUT_SECONDS)
}
// Ensure they're not readable by child processes.
delete process.env.PASSWORD
delete process.env.HASHED_PASSWORD

View File

@@ -1,5 +1,6 @@
import { logger } from "@coder/logger"
import { promises as fs } from "fs"
import { Emitter } from "../common/emitter"
/**
* Provides a heartbeat using a local file to indicate activity.
@@ -8,6 +9,9 @@ export class Heart {
private heartbeatTimer?: NodeJS.Timeout
private heartbeatInterval = 60000
public lastHeartbeat = 0
private readonly _onChange = new Emitter<"alive" | "expired" | "unknown">()
readonly onChange = this._onChange.event
private state: "alive" | "expired" | "unknown" = "expired"
public constructor(
private readonly heartbeatPath: string,
@@ -17,6 +21,13 @@ export class Heart {
this.alive = this.alive.bind(this)
}
private setState(state: typeof this.state) {
if (this.state !== state) {
this.state = state
this._onChange.emit(this.state)
}
}
public alive(): boolean {
const now = Date.now()
return now - this.lastHeartbeat < this.heartbeatInterval
@@ -28,6 +39,7 @@ export class Heart {
*/
public async beat(): Promise<void> {
if (this.alive()) {
this.setState("alive")
return
}
@@ -36,7 +48,22 @@ export class Heart {
if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer)
}
this.heartbeatTimer = setTimeout(() => heartbeatTimer(this.isActive, this.beat), this.heartbeatInterval)
this.heartbeatTimer = setTimeout(async () => {
try {
if (await this.isActive()) {
this.beat()
} else {
this.setState("expired")
}
} catch (error: unknown) {
logger.warn((error as Error).message)
this.setState("unknown")
}
}, this.heartbeatInterval)
this.setState("alive")
try {
return await fs.writeFile(this.heartbeatPath, "")
} catch (error: any) {
@@ -53,20 +80,3 @@ export class Heart {
}
}
}
/**
* Helper function for the heartbeatTimer.
*
* If heartbeat is active, call beat. Otherwise do nothing.
*
* Extracted to make it easier to test.
*/
export async function heartbeatTimer(isActive: Heart["isActive"], beat: Heart["beat"]) {
try {
if (await isActive()) {
beat()
}
} catch (error: unknown) {
logger.warn((error as Error).message)
}
}

View File

@@ -11,6 +11,7 @@ import { loadCustomStrings } from "./i18n"
import { register } from "./routes"
import { VSCodeModule } from "./routes/vscode"
import { isDirectory, open } from "./util"
import { wrapper } from "./wrapper"
/**
* Return true if the user passed an extension-related VS Code flag.
@@ -141,7 +142,7 @@ export const runCodeServer = async (
const app = await createApp(args)
const protocol = args.cert ? "https" : "http"
const serverAddress = ensureAddress(app.server, protocol)
const disposeRoutes = await register(app, args)
const { disposeRoutes, heart } = await register(app, args)
logger.info(`Using config file ${args.config}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
@@ -166,6 +167,27 @@ export const runCodeServer = async (
logger.info(" - Not serving HTTPS")
}
if (args["idle-timeout-seconds"]) {
logger.info(` - Idle timeout set to ${args["idle-timeout-seconds"]} seconds`)
let idleShutdownTimer: NodeJS.Timeout | undefined
const startIdleShutdownTimer = () => {
idleShutdownTimer = setTimeout(() => {
logger.warn(`Idle timeout of ${args["idle-timeout-seconds"]} seconds exceeded`)
wrapper.exit(0)
}, args["idle-timeout-seconds"]! * 1000)
}
startIdleShutdownTimer()
heart.onChange((state) => {
clearTimeout(idleShutdownTimer)
if (state === "expired") {
startIdleShutdownTimer()
}
})
}
if (args["disable-proxy"]) {
logger.info(" - Proxy disabled")
} else if (args["proxy-domain"].length > 0) {

View File

@@ -28,7 +28,10 @@ import * as vscode from "./vscode"
/**
* Register all routes and middleware.
*/
export const register = async (app: App, args: DefaultedArgs): Promise<Disposable["dispose"]> => {
export const register = async (
app: App,
args: DefaultedArgs,
): Promise<{ disposeRoutes: Disposable["dispose"]; heart: Heart }> => {
const heart = new Heart(path.join(paths.data, "heartbeat"), async () => {
return new Promise((resolve, reject) => {
// getConnections appears to not call the callback when there are no more
@@ -173,8 +176,11 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use(errorHandler)
app.wsRouter.use(wsErrorHandler)
return () => {
heart.dispose()
vscode.dispose()
return {
disposeRoutes: () => {
heart.dispose()
vscode.dispose()
},
heart,
}
}

26
test/package-lock.json generated
View File

@@ -7,7 +7,7 @@
"license": "MIT",
"devDependencies": {
"@jest-mock/express": "^1.4.5",
"@playwright/test": "^1.46.0",
"@playwright/test": "^1.56.1",
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13",
"@types/node-fetch": "^2.5.8",
@@ -18,7 +18,7 @@
"jest-fetch-mock": "^3.0.3",
"jsdom": "^16.4.0",
"node-fetch": "^2.6.7",
"playwright": "^1.46.0",
"playwright": "^1.56.1",
"ts-jest": "^27.0.7",
"wtfnode": "^0.9.1"
}
@@ -1012,13 +1012,13 @@
}
},
"node_modules/@playwright/test": {
"version": "1.47.2",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz",
"integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==",
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz",
"integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.47.2"
"playwright": "1.56.1"
},
"bin": {
"playwright": "cli.js"
@@ -4305,13 +4305,13 @@
}
},
"node_modules/playwright": {
"version": "1.47.2",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz",
"integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==",
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz",
"integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.47.2"
"playwright-core": "1.56.1"
},
"bin": {
"playwright": "cli.js"
@@ -4324,9 +4324,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.47.2",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz",
"integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==",
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz",
"integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@@ -3,7 +3,7 @@
"#": "We must put jest in a sub-directory otherwise VS Code somehow picks up the types and generates conflicts with mocha.",
"devDependencies": {
"@jest-mock/express": "^1.4.5",
"@playwright/test": "^1.46.0",
"@playwright/test": "^1.56.1",
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13",
"@types/node-fetch": "^2.5.8",
@@ -14,7 +14,7 @@
"jest-fetch-mock": "^3.0.3",
"jsdom": "^16.4.0",
"node-fetch": "^2.6.7",
"playwright": "^1.46.0",
"playwright": "^1.56.1",
"ts-jest": "^27.0.7",
"wtfnode": "^0.9.1"
},

View File

@@ -1,6 +1,6 @@
import { logger } from "@coder/logger"
import { readFile, writeFile, stat, utimes } from "fs/promises"
import { Heart, heartbeatTimer } from "../../../src/node/heart"
import { Heart } from "../../../src/node/heart"
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
@@ -82,7 +82,52 @@ describe("Heart", () => {
})
describe("heartbeatTimer", () => {
beforeAll(() => {
const testName = "heartbeatTimer"
let testDir = ""
beforeAll(async () => {
await clean(testName)
testDir = await tmpdir(testName)
mockLogger()
})
afterAll(() => {
jest.restoreAllMocks()
})
beforeEach(() => {
jest.useFakeTimers()
})
afterEach(() => {
jest.resetAllMocks()
jest.clearAllTimers()
jest.useRealTimers()
})
it("should call isActive when timeout expires", async () => {
const isActive = true
const mockIsActive = jest.fn().mockResolvedValue(isActive)
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
await heart.beat()
jest.advanceTimersByTime(60 * 1000)
expect(mockIsActive).toHaveBeenCalled()
})
it("should log a warning when isActive rejects", async () => {
const errorMsg = "oh no"
const error = new Error(errorMsg)
const mockIsActive = jest.fn().mockRejectedValue(error)
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
await heart.beat()
jest.advanceTimersByTime(60 * 1000)
expect(mockIsActive).toHaveBeenCalled()
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
})
})
describe("stateChange", () => {
const testName = "stateChange"
let testDir = ""
let heart: Heart
beforeAll(async () => {
await clean(testName)
testDir = await tmpdir(testName)
mockLogger()
})
afterAll(() => {
@@ -90,23 +135,28 @@ describe("heartbeatTimer", () => {
})
afterEach(() => {
jest.resetAllMocks()
if (heart) {
heart.dispose()
}
})
it("should call beat when isActive resolves to true", async () => {
const isActive = true
const mockIsActive = jest.fn().mockResolvedValue(isActive)
const mockBeatFn = jest.fn()
await heartbeatTimer(mockIsActive, mockBeatFn)
expect(mockIsActive).toHaveBeenCalled()
expect(mockBeatFn).toHaveBeenCalled()
it("should change to alive after a beat", async () => {
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
const mockOnChange = jest.fn()
heart.onChange(mockOnChange)
await heart.beat()
expect(mockOnChange.mock.calls[0][0]).toBe("alive")
})
it("should log a warning when isActive rejects", async () => {
const errorMsg = "oh no"
const error = new Error(errorMsg)
const mockIsActive = jest.fn().mockRejectedValue(error)
const mockBeatFn = jest.fn()
await heartbeatTimer(mockIsActive, mockBeatFn)
expect(mockIsActive).toHaveBeenCalled()
expect(mockBeatFn).not.toHaveBeenCalled()
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
it.only("should change to expired when not active", async () => {
jest.useFakeTimers()
heart = new Heart(`${testDir}/shutdown.txt`, () => new Promise((resolve) => resolve(false)))
const mockOnChange = jest.fn()
heart.onChange(mockOnChange)
await heart.beat()
await jest.advanceTimersByTime(60 * 1000)
expect(mockOnChange.mock.calls[1][0]).toBe("expired")
jest.clearAllTimers()
jest.useRealTimers()
})
})

View File

@@ -16,6 +16,7 @@ jest.mock("@coder/logger", () => ({
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
named: jest.fn(),
level: 0,
},
field: jest.fn(),
@@ -94,7 +95,7 @@ describe("main", () => {
// Mock routes module
jest.doMock("../../../src/node/routes", () => ({
register: jest.fn().mockResolvedValue(jest.fn()),
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
}))
// Mock loadCustomStrings to succeed
@@ -131,7 +132,7 @@ describe("main", () => {
// Mock routes module
jest.doMock("../../../src/node/routes", () => ({
register: jest.fn().mockResolvedValue(jest.fn()),
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
}))
// Import runCodeServer after mocking