Compare commits

...

50 commits

Author SHA1 Message Date
Asher
472bf8a5fa
Remove homebrew step
It has been broken for a long time (No available formula with the name
"code-server") but it looks like they have their own bot publishing
updates anyway.
2025-12-02 13:38:27 -09:00
dependabot[bot]
eccb1eb537
chore: bump actions/setup-node from 4 to 6 (#7550) 2025-12-02 13:04:45 -09:00
Asher
f128a7ac11
Update actionlint to 1.7.9 2025-12-01 12:55:13 -09:00
Asher
80996d2e08
Add VS Code web to the bug template 2025-12-01 12:49:28 -09:00
dependabot[bot]
9819b91c74
chore: bump actions/checkout from 5 to 6 (#7585) 2025-12-01 12:47:25 -09:00
Olivier Benz
2ed1098c1e
Update Code to 1.106.3 (#7583) 2025-12-01 11:52:45 -09:00
Asher
85042e2910
Note settings change from VS Code web and Codespaces 2025-11-25 14:39:16 -09:00
Asher
904942a194
Increase build timeout 2025-11-19 14:02:53 -09:00
Olivier Benz
9a24e467b2
Update Code to 1.106.2 (#7571) 2025-11-19 12:54:38 -09:00
Olivier Benz
24a777491b
Update Code to 1.106.1 (#7570) 2025-11-19 09:09:30 -09:00
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
Olexandr88
54b33a75e0
Add Discord link to readme (#7465) 2025-08-25 10:32:11 -08:00
Olivier Benz
3c5deac16d
Update Code to 1.103.2 (#7463) 2025-08-25 09:32:20 -08:00
Olivier Benz
fbaadbcfbc
Update Code to 1.103.1 (#7459) 2025-08-15 12:31:17 -08:00
Asher
2bbb6e8cca
Release v4.103.0 2025-08-12 14:31:17 -08:00
Olivier Benz
f1236d80b9
Update Code to 1.103.0 (#7458) 2025-08-08 17:10:23 -08:00
dependabot[bot]
b27d982c67
chore: bump prettier from 3.4.2 to 3.6.2 (#7407) 2025-08-04 12:46:32 -08:00
Asher
3f23840756 Remove import from express-serve-static-core
Mostly because express-serve-static-core is an implicit dependency.  We
could make it explicit, but the type we imported from it is just an
alias for qs.ParsedQs anyway.
2025-08-04 12:26:46 -08:00
Asher
e54467fb85 Run npm audit fix 2025-08-04 12:26:46 -08:00
Asher
8f738d29f2 Remove unused supertest dependency 2025-08-04 12:26:46 -08:00
Asher
5c0ff5013f Remove direct safe-buffer dependency
We do not use it directly.
2025-08-04 12:26:46 -08:00
dependabot[bot]
8a378df6e5
chore: bump eslint-import-resolver-typescript from 3.8.3 to 4.4.4 (#7404) 2025-08-04 11:37:04 -08:00
dependabot[bot]
a7e77ce4af
chore: bump dawidd6/action-download-artifact from 10 to 11 (#7409)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 10 to 11.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/v10...v11)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-version: '11'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:35:59 -08:00
dependabot[bot]
794def9a77
chore: bump on-headers and compression (#7427)
Bumps [on-headers](https://github.com/jshttp/on-headers) to 1.1.0 and updates ancestor dependency [compression](https://github.com/expressjs/compression). These dependencies need to be updated together.


Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `compression` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
- dependency-name: compression
  dependency-version: 1.8.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:33:51 -08:00
Asher
b5a2ce2522
Use error handler in session server (#7455) 2025-08-04 11:05:48 -08:00
dependabot[bot]
bc15fa461c
chore: bump form-data in /test (#7430)
---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 10:31:50 -08:00
dependabot[bot]
1805daed07
chore: bump aquasecurity/trivy-action from 0.31.0 to 0.32.0 (#7450)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.31.0 to 0.32.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](76071ef0d7...dc5a429b52)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 10:31:21 -08:00
Olivier Benz
6f3d0a7e5a
Update Code to 1.102.3 (#7444) 2025-07-30 11:28:34 -08:00
Asher
b1ad6ffcb9
Release v4.102.2 2025-07-24 14:08:12 -08:00
51 changed files with 1131 additions and 906 deletions

View file

@ -86,6 +86,18 @@ body:
validations: validations:
required: true required: true
- type: dropdown
attributes:
label: Does this bug reproduce in VS Code web?
description: If the bug reproduces in VS Code web, submit the issue upstream instead (https://github.com/microsoft/vscode). You can run VS Code web with `code serve-web`.
options:
- Yes, this is also broken in VS Code web
- No, this works as expected in VS Code web
- This cannot be tested in VS Code web
- I did not test VS Code web
validations:
required: true
- type: dropdown - type: dropdown
attributes: attributes:
label: Does this bug reproduce in GitHub Codespaces? label: Does this bug reproduce in GitHub Codespaces?

View file

@ -32,7 +32,7 @@ jobs:
helm: ${{ steps.filter.outputs.helm }} helm: ${{ steps.filter.outputs.helm }}
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Check changed files - name: Check changed files
uses: dorny/paths-filter@v3 uses: dorny/paths-filter@v3
id: filter id: filter
@ -64,8 +64,8 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 5 timeout-minutes: 5
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -82,8 +82,8 @@ jobs:
needs: changes needs: changes
if: needs.changes.outputs.docs == 'true' if: needs.changes.outputs.docs == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -100,7 +100,7 @@ jobs:
needs: changes needs: changes
if: needs.changes.outputs.helm == 'true' if: needs.changes.outputs.helm == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: azure/setup-helm@v4 - uses: azure/setup-helm@v4
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
@ -114,8 +114,8 @@ jobs:
needs: changes needs: changes
if: needs.changes.outputs.code == 'true' if: needs.changes.outputs.code == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -132,11 +132,11 @@ jobs:
if: needs.changes.outputs.ci == 'true' if: needs.changes.outputs.ci == 'true'
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Check workflow files - name: Check workflow files
run: | run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.1 bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.9
./actionlint -color -shellcheck= -ignore "set-output" ./actionlint -color -shellcheck= -ignore "softprops/action-gh-release"
shell: bash shell: bash
test-unit: test-unit:
@ -146,8 +146,8 @@ jobs:
needs: changes needs: changes
if: needs.changes.outputs.code == 'true' if: needs.changes.outputs.code == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -164,12 +164,12 @@ jobs:
build: build:
name: Build code-server name: Build code-server
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 60 timeout-minutes: 70
env: env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
DISABLE_V8_COMPILE_CACHE: 1 DISABLE_V8_COMPILE_CACHE: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
with: with:
submodules: true submodules: true
- run: sudo apt update && sudo apt install -y libkrb5-dev - run: sudo apt update && sudo apt install -y libkrb5-dev
@ -178,7 +178,7 @@ jobs:
packages: quilt packages: quilt
version: 1.0 version: 1.0
- run: quilt push -a - run: quilt push -a
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -231,9 +231,9 @@ jobs:
needs: [changes, build] needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- run: sudo apt update && sudo apt install -y libkrb5-dev - run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -241,7 +241,7 @@ jobs:
package-lock.json package-lock.json
test/package-lock.json test/package-lock.json
- run: SKIP_SUBMODULE_DEPS=1 npm ci - run: SKIP_SUBMODULE_DEPS=1 npm ci
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v5
with: with:
name: npm-package name: npm-package
- run: tar -xzf package.tar.gz - run: tar -xzf package.tar.gz
@ -265,9 +265,9 @@ jobs:
needs: [changes, build] needs: [changes, build]
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true' if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- run: sudo apt update && sudo apt install -y libkrb5-dev - run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: actions/setup-node@v4 - uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
cache: npm cache: npm
@ -275,7 +275,7 @@ jobs:
package-lock.json package-lock.json
test/package-lock.json test/package-lock.json
- run: SKIP_SUBMODULE_DEPS=1 npm ci - run: SKIP_SUBMODULE_DEPS=1 npm ci
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v5
with: with:
name: npm-package name: npm-package
- run: tar -xzf package.tar.gz - run: tar -xzf package.tar.gz

View file

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

View file

@ -25,10 +25,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code-server - name: Checkout code-server
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
@ -53,38 +53,6 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_ENVIRONMENT: "production" NPM_ENVIRONMENT: "production"
homebrew:
needs: npm
runs-on: ubuntu-latest
steps:
# Ensure things are up to date
# Suggested by homebrew maintainers
# https://github.com/Homebrew/discussions/discussions/1532#discussioncomment-782633
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Checkout code-server
uses: actions/checkout@v4
- name: Configure git
run: |
git config --global user.name cdrci
git config --global user.email opensource@coder.com
# Strip out the v (v4.9.1 -> 4.9.1).
- name: Get and set VERSION
run: |
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Bump code-server homebrew version
env:
VERSION: ${{ env.VERSION }}
HOMEBREW_GITHUB_API_TOKEN: ${{secrets.HOMEBREW_GITHUB_API_TOKEN}}
run: ./ci/steps/brew-bump.sh
aur: aur:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10 timeout-minutes: 10
@ -94,13 +62,13 @@ jobs:
steps: steps:
# We need to checkout code-server so we can get the version # We need to checkout code-server so we can get the version
- name: Checkout code-server - name: Checkout code-server
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
fetch-depth: 0 fetch-depth: 0
path: "./code-server" path: "./code-server"
- name: Checkout code-server-aur repo - name: Checkout code-server-aur repo
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
repository: "cdrci/code-server-aur" repository: "cdrci/code-server-aur"
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }} token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
@ -148,7 +116,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code-server - name: Checkout code-server
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3

View file

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

View file

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

View file

@ -25,12 +25,12 @@ jobs:
timeout-minutes: 15 timeout-minutes: 15
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version-file: .node-version node-version-file: .node-version
@ -46,12 +46,12 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
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@76071ef0d7ec797419534a183b498b4d6366cf37 uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
with: with:
scan-type: "fs" scan-type: "fs"
scan-ref: "." scan-ref: "."
@ -76,7 +76,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View file

@ -48,10 +48,10 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Run Trivy vulnerability scanner in image mode - name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
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 @@
22.15.1 22.20.0

View file

@ -22,6 +22,67 @@ Code v99.99.999
## Unreleased ## 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
### Changed
- Update to Code 1.103.0.
## [4.102.2](https://github.com/coder/code-server/releases/tag/v4.102.2) - 2025-07-24
Code v1.102.2
### Changed
- Update to Code 1.102.2.
## [4.102.1](https://github.com/coder/code-server/releases/tag/v4.102.1) - 2025-07-17 ## [4.102.1](https://github.com/coder/code-server/releases/tag/v4.102.1) - 2025-07-17
Code v1.102.1 Code v1.102.1
@ -802,7 +863,6 @@ Code v1.68.1
would be accessible at `my.domain/proxy/8000/` without any authentication. would be accessible at `my.domain/proxy/8000/` without any authentication.
If all of the following apply to you please update as soon as possible: If all of the following apply to you please update as soon as possible:
- You run code-server with the built-in password authentication. - You run code-server with the built-in password authentication.
- You run unprotected HTTP services on ports accessible by code-server. - You run unprotected HTTP services on ports accessible by code-server.

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.29.1 version: 3.31.2
# 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.102.1 appVersion: 4.104.2

View file

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

View file

@ -6,7 +6,7 @@ replicaCount: 1
image: image:
repository: codercom/code-server repository: codercom/code-server
tag: '4.102.1' tag: '4.104.2'
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
@ -31,6 +31,9 @@ serviceAccount:
# If not set and create is true, a name is generated using the fullname template # If not set and create is true, a name is generated using the fullname template
name: "" name: ""
# Specifies annotations for deployment
annotations: {}
podAnnotations: {} podAnnotations: {}
podSecurityContext: {} podSecurityContext: {}

View file

@ -31,6 +31,7 @@
- [What's the difference between code-server and Theia?](#whats-the-difference-between-code-server-and-theia) - [What's the difference between code-server and Theia?](#whats-the-difference-between-code-server-and-theia)
- [What's the difference between code-server and OpenVSCode-Server?](#whats-the-difference-between-code-server-and-openvscode-server) - [What's the difference between code-server and OpenVSCode-Server?](#whats-the-difference-between-code-server-and-openvscode-server)
- [What's the difference between code-server and GitHub Codespaces?](#whats-the-difference-between-code-server-and-github-codespaces) - [What's the difference between code-server and GitHub Codespaces?](#whats-the-difference-between-code-server-and-github-codespaces)
- [What's the difference between code-server and VS Code web?](#whats-the-difference-between-code-server-and-vs-code-web)
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation) - [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server) - [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
- [How do I change the port?](#how-do-i-change-the-port) - [How do I change the port?](#how-do-i-change-the-port)
@ -322,12 +323,8 @@ As long as there is an active browser connection, code-server touches
`~/.local/share/code-server/heartbeat` once a minute. `~/.local/share/code-server/heartbeat` once a minute.
If you want to shutdown code-server if there hasn't been an active connection 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 after a predetermined amount of time, you can use the --idle-timeout-seconds flag
the last modified time on the heartbeat file. If it is older than X minutes (or or set an `CODE_SERVER_IDLE_TIMEOUT_SECONDS` environment variable.
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.
## How do I change the password? ## How do I change the password?
@ -443,6 +440,8 @@ Specific changes include:
- The ability to use your own marketplace and collect your own telemetry - The ability to use your own marketplace and collect your own telemetry
- Built-in proxy for accessing ports on the remote machine integrated into - Built-in proxy for accessing ports on the remote machine integrated into
VS Code's ports panel VS Code's ports panel
- Settings are stored on disk like desktop VS Code, instead of in browser
storage (note that state is still stored in browser storage).
- Wrapper process that spawns VS Code on-demand and has a separate CLI - Wrapper process that spawns VS Code on-demand and has a separate CLI
- Notification when updates are available - Notification when updates are available
- [Some other things](https://github.com/coder/code-server/tree/main/patches) - [Some other things](https://github.com/coder/code-server/tree/main/patches)
@ -451,6 +450,12 @@ Some of these changes appear very unlikely to ever be adopted by Microsoft.
Some may make their way upstream, further closing the gap, but at the moment it Some may make their way upstream, further closing the gap, but at the moment it
looks like there will always be some subtle differences. looks like there will always be some subtle differences.
## What's the difference between code-server and VS Code web?
VS Code web (which can be ran using `code serve-web`) has the same differences
as the Codespaces section above. VS Code web can be a better choice if you need
access to the official Microsoft marketplace.
## Does code-server have any security login validation? ## Does code-server have any security login validation?
code-server supports setting a single password and limits logins to two per code-server supports setting a single password and limits logins to two per

View file

@ -1,6 +1,6 @@
# code-server # code-server
[!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See latest](https://img.shields.io/static/v1?label=Docs&message=see%20latest&color=blue)](https://coder.com/docs/code-server/latest) [!["GitHub Discussions"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true&logo=github&colorB=purple)](https://github.com/coder/code-server/discussions) [!["Join us on Slack"](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://coder.com/community) [![Twitter Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=social)](https://twitter.com/coderhq) [![Discord](https://img.shields.io/discord/747933592273027093)](https://discord.com/invite/coder) [![codecov](https://codecov.io/gh/coder/code-server/branch/main/graph/badge.svg?token=5iM9farjnC)](https://codecov.io/gh/coder/code-server) [![See latest](https://img.shields.io/static/v1?label=Docs&message=see%20latest&color=blue)](https://coder.com/docs/code-server/latest)
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
access it in the browser. access it in the browser.

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: 7. Install and use Node.js 22:
```shell ```shell
nvm install 18 nvm install 22
nvm use 18 nvm use 22
``` ```
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`

View file

@ -82,13 +82,11 @@ _exact_ same commands presented in the rest of this document.
- For Arch Linux, code-server will install the AUR package. - For Arch Linux, code-server will install the AUR package.
- For any unrecognized Linux operating system, code-server will install the - For any unrecognized Linux operating system, code-server will install the
latest standalone release into `~/.local`. latest standalone release into `~/.local`.
- Ensure that you add `~/.local/bin` to your `$PATH` to run code-server. - Ensure that you add `~/.local/bin` to your `$PATH` to run code-server.
- For macOS, code-server will install the Homebrew package (if you don't have - For macOS, code-server will install the Homebrew package (if you don't have
Homebrew installed, code-server will install the latest standalone release Homebrew installed, code-server will install the latest standalone release
into `~/.local`). into `~/.local`).
- Ensure that you add `~/.local/bin` to your `$PATH` to run code-server. - Ensure that you add `~/.local/bin` to your `$PATH` to run code-server.
- For FreeBSD, code-server will install the [npm package](#npm) with `npm` - For FreeBSD, code-server will install the [npm package](#npm) with `npm`

@ -1 +1 @@
Subproject commit c306e94f98122556ca081f527b466015e1bc37b0 Subproject commit bf9252a2fb45be6893dd8870c0bf37e2e1766d61

913
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -57,11 +57,11 @@
"doctoc": "^2.2.1", "doctoc": "^2.2.1",
"eslint": "^9.12.0", "eslint": "^9.12.0",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.6.0", "eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.28.1", "eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^5.0.0", "eslint-plugin-prettier": "^5.0.0",
"globals": "^16.1.0", "globals": "^16.1.0",
"prettier": "3.4.2", "prettier": "3.6.2",
"prettier-plugin-sh": "^0.14.0", "prettier-plugin-sh": "^0.14.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^5.6.2", "typescript": "^5.6.2",
@ -83,7 +83,6 @@
"proxy-agent": "^6.3.1", "proxy-agent": "^6.3.1",
"qs": "6.14.0", "qs": "6.14.0",
"rotating-file-stream": "^3.1.1", "rotating-file-stream": "^3.1.1",
"safe-buffer": "^5.2.1",
"safe-compare": "^1.1.4", "safe-compare": "^1.1.4",
"semver": "^7.5.4", "semver": "^7.5.4",
"ws": "^8.14.2", "ws": "^8.14.2",

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
@@ -223,7 +223,9 @@ class RemoteAuthoritiesImpl { @@ -237,7 +237,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}`,
@ -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.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
+++ code-server/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> { connect({ host, port }: WebSocketRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
return new Promise<ISocket>((resolve, reject) => { return new Promise<ISocket>((resolve, reject) => {
const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws'); const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws');
+ path = (mainWindow.location.pathname + "/" + path).replace(/\/\/+/g, "/") + 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 socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError(reject); const disposables = new DisposableStore();
socket.onOpen(() => { disposables.add(socket.onError(reject));
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts 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
@ -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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 { export interface IProductConfiguration {
readonly codeServerVersion?: string 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.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts +++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
@@ -333,7 +333,8 @@ class LocalStorageURLCallbackProvider ex @@ -339,7 +339,8 @@ class LocalStorageURLCallbackProvider ex
this.startListening(); this.startListening();
} }
@ -263,7 +263,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
} }
private startListening(): void { private startListening(): void {
@@ -578,17 +579,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 () { (function () {
// Find config by checking for DOM // Find config by checking for DOM
@@ -597,8 +587,8 @@ function readCookie(name: string): strin @@ -604,8 +594,8 @@ function readCookie(name: string): strin
if (!configElement || !configElementAttribute) { if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element'); 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.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 @@ -107,10 +107,14 @@ class RemoteTerminalBackend extends Base
} }
const reqId = e.reqId; const reqId = e.reqId;
const commandId = e.commandId; 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.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
@@ -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.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts +++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
@@ -134,6 +134,7 @@ export interface NativeParsedArgs { @@ -137,6 +137,7 @@ export interface NativeParsedArgs {
'disable-chromium-sandbox'?: boolean; 'disable-chromium-sandbox'?: boolean;
sandbox?: boolean; sandbox?: boolean;
'enable-coi'?: 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.orig/lib/vscode/src/vs/platform/environment/node/argv.ts
+++ code-server/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.") }, '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.") }, '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.") }, 'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },

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
@@ -340,6 +340,10 @@ export class Extension implements IExten @@ -341,6 +341,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

@ -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 +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -12,7 +12,7 @@ import * as path from '../../base/common @@ -12,7 +12,7 @@ import * as path from '../../base/common
import { IURITransformer } from '../../base/common/uriIpc.js'; 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 { Promises } from '../../base/node/pfs.js';
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from '../../base/parts/ipc/common/ipc.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 { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js'; import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
import { ConfigurationService } from '../../platform/configuration/common/configurationService.js'; import { ConfigurationService } from '../../platform/configuration/common/configurationService.js';
@@ -267,6 +267,9 @@ export async function setupServerService @@ -272,6 +272,9 @@ export async function setupServerService
socketServer.registerChannel('mcpManagement', new McpManagementChannel(mcpManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority))); socketServer.registerChannel('mcpManagement', new McpManagementChannel(mcpManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)));
@ -198,7 +198,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -109,6 +110,7 @@ export interface ServerParsedArgs { @@ -110,6 +111,7 @@ export interface ServerParsedArgs {
'disable-file-downloads'?: boolean; 'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean; 'disable-file-uploads'?: boolean;
'disable-getting-started-override'?: boolean, 'disable-getting-started-override'?: boolean,
@ -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.orig/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts +++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
@@ -53,7 +53,7 @@ import './services/dialogs/browser/fileD @@ -55,7 +55,7 @@ import './services/dialogs/browser/fileD
import './services/host/browser/browserHostService.js'; import './services/host/browser/browserHostService.js';
import './services/lifecycle/browser/lifecycleService.js'; import './services/lifecycle/browser/lifecycleService.js';
import './services/clipboard/browser/clipboardService.js'; import './services/clipboard/browser/clipboardService.js';

View file

@ -99,7 +99,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -103,6 +105,8 @@ export interface ServerParsedArgs { @@ -104,6 +106,8 @@ export interface ServerParsedArgs {
/* ----- code-server ----- */ /* ----- code-server ----- */
'disable-update-check'?: boolean; 'disable-update-check'?: boolean;
'auth'?: string; 'auth'?: string;
@ -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.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 '../../base/common @@ -6,10 +6,10 @@
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js'; import { Disposable } from '../../base/common/lifecycle.js';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.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 { 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, 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, 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 } from '../common/contextkeys.js';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
-import { IWorkbenchEnvironmentService } from '../services/environment/common/environmentService.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 { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from '../../platform/workspace/common/workspace.js';
import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js'; import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js';
import { getRemoteName } from '../../platform/remote/common/remoteHosts.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, @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,
@ -148,7 +147,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@IProductService private readonly productService: IProductService, @IProductService private readonly productService: IProductService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IEditorService private readonly editorService: IEditorService, @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 = AuxiliaryBarMaximizedContext.bindTo(this.contextKeyService);
this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized()); 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.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts +++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -36,6 +36,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 IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', 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, @IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IPathService protected readonly pathService: IPathService, @IPathService protected readonly pathService: IPathService,
@IKeybindingService private readonly keybindingService: IKeybindingService, @IKeybindingService private readonly keybindingService: IKeybindingService,
@@ -310,20 +310,22 @@ export class SimpleFileDialog extends Di @@ -311,20 +311,22 @@ export class SimpleFileDialog extends Di
this.filePickBox.ignoreFocusOut = true; this.filePickBox.placeholder = nls.localize('remoteFileDialog.placeholder', "Folder path");
this.filePickBox.ok = true; this.filePickBox.ok = true;
this.filePickBox.okLabel = typeof this.options.openLabel === 'string' ? this.options.openLabel : this.options.openLabel?.withoutMnemonic; 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)) { - 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 { WorkbenchCompressibleAsyncDataTree } from '../../../../../platform/list/browser/listService.js';
import { ISearchService, QueryType, getExcludes, ISearchConfiguration, ISearchComplete, IFileQuery } from '../../../../services/search/common/search.js'; import { ISearchService, QueryType, getExcludes, ISearchConfiguration, ISearchComplete, IFileQuery } from '../../../../services/search/common/search.js';
import { CancellationToken } from '../../../../../base/common/cancellation.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, @IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService, @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) => { const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => {
if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) { 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) // External file DND (Import/Upload file)
if (data instanceof NativeDragAndDropData) { 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 { renderFormattedText } from '../../../../base/browser/formattedTextRenderer.js';
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js'; import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
import { Button } from '../../../../base/browser/ui/button/button.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 { OpenRecentAction } from '../../../browser/actions/windowActions.js';
import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from '../../../browser/actions/workspaceActions.js'; import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from '../../../browser/actions/workspaceActions.js';
import { EditorPane } from '../../../browser/parts/editor/editorPane.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 { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js';
import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js'; import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js';
import './gettingStartedColors.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")) $('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', {},);
@@ -911,6 +977,9 @@ export class GettingStartedPage extends @@ -937,6 +1003,9 @@ export class GettingStartedPage extends
recentList.setLimit(5); recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
} }
@ -189,7 +189,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -107,6 +108,7 @@ export interface ServerParsedArgs { @@ -108,6 +109,7 @@ export interface ServerParsedArgs {
'auth'?: string; 'auth'?: string;
'disable-file-downloads'?: boolean; 'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean; 'disable-file-uploads'?: boolean;
@ -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.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,7 +7,7 @@ import { Event } from '../../base/common @@ -6,7 +6,7 @@
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js'; import { Disposable } from '../../base/common/lifecycle.js';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.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 { 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, 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, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js'; +import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
import { IConfigurationService } from '../../platform/configuration/common/configuration.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 // 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)
@ -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.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts +++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -38,6 +38,7 @@ export const EmbedderIdentifierContext = @@ -41,6 +41,7 @@ export const InAutomationContext = new R
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true); export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', 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); const envKeys = Object.keys(env);
envKeys 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 Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
=================================================================== ===================================================================
--- /dev/null --- /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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 { 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.orig/lib/vscode/src/server-main.ts
+++ code-server/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'); 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 +// 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. +// 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 // Do a quick parse to determine if a server or the cli needs to be started
const parsedArgs = minimist(process.argv.slice(2), { const parsedArgs = minimist(process.argv.slice(2), {
boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'], 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 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', + osLocale: 'en',
+ commit: product.commit, + commit: product.commit,
+ userDataPath: '', + userDataPath: '',
+ nlsMetadataPath: __dirname, + nlsMetadataPath: import.meta.dirname,
+ }); + });
+ return loadCode(nlsConfiguration); + return loadCode(nlsConfiguration);
+} +}
@ -322,3 +304,21 @@ Index: code-server/lib/vscode/src/server-main.ts
+if (!process.env.CODE_SERVER_PARENT_PID) { +if (!process.env.CODE_SERVER_PARENT_PID) {
+ start(); + 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 +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO @@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO
*/ */
readonly configurationDefaults?: Record<string, any>; readonly configurationDefaults?: Record<string, unknown>;
+ /** + /**
+ * Path to the user data directory. + * Path to the user data directory.
@ -79,7 +79,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/configuration/browser/co
}); });
})); }));
@@ -555,6 +557,12 @@ export class WorkspaceService extends Di @@ -556,6 +558,12 @@ export class WorkspaceService extends Di
previousFolders = this.workspace.folders; previousFolders = this.workspace.folders;
this.workspace.update(workspace); this.workspace.update(workspace);
} else { } else {

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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 codeServerVersion?: string
readonly rootEndpoint?: string readonly rootEndpoint?: string
readonly updateEndpoint?: string readonly updateEndpoint?: string
@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -101,6 +102,7 @@ export const serverOptions: OptionDescri @@ -102,6 +103,7 @@ export const serverOptions: OptionDescri
export interface ServerParsedArgs { export interface ServerParsedArgs {
/* ----- code-server ----- */ /* ----- code-server ----- */
'disable-update-check'?: boolean; 'disable-update-check'?: boolean;

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.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/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 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 || { + extensionsGallery: env.EXTENSIONS_GALLERY ? JSON.parse(env.EXTENSIONS_GALLERY) : (product.extensionsGallery || {
+ serviceUrl: "https://open-vsx.org/vscode/gallery", + serviceUrl: "https://open-vsx.org/vscode/gallery",
+ itemUrl: "https://open-vsx.org/vscode/item", + 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}", + resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
+ controlUrl: "", + controlUrl: "",
+ recommendationsUrl: "", + recommendationsUrl: "",

View file

@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
@@ -314,10 +314,7 @@ function extensionDescriptionArrayToMap( @@ -321,10 +321,7 @@ function extensionDescriptionArrayToMap(
} }
export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean {

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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 rootEndpoint?: string
readonly updateEndpoint?: string readonly updateEndpoint?: string
readonly logoutEndpoint?: 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.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 @@ -292,7 +292,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
@ -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 type { IURLCallbackProvider } from '../../../workbench/services/url/browser/urlService.js';
import { create } from '../../../workbench/workbench.web.main.internal.js'; import { create } from '../../../workbench/workbench.web.main.internal.js';
@@ -599,6 +600,39 @@ class WorkspaceProvider implements IWork @@ -606,6 +607,39 @@ class WorkspaceProvider implements IWork
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined, settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config), workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), 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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 updateEndpoint?: string
readonly logoutEndpoint?: string readonly logoutEndpoint?: string
readonly proxyEndpointTemplate?: 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 minimist from 'minimist';
import * as nativeWatchdog from 'native-watchdog'; import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net'; 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 // 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 { NullPolicyService } from '../../platform/policy/common/policy.js';
import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js'; import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js';
import { LoggerService } from '../../platform/log/node/loggerService.js'; import { LoggerService } from '../../platform/log/node/loggerService.js';
@@ -163,11 +165,23 @@ export async function setupServerService @@ -166,11 +168,23 @@ export async function setupServerService
const requestService = new RequestService('remote', configurationService, environmentService, logService); const requestService = new RequestService('remote', configurationService, environmentService, logService);
services.set(IRequestService, requestService); 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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 path: string;
readonly scope: 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.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/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}", resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
controlUrl: "", controlUrl: "",
recommendationsUrl: "", recommendationsUrl: "",

View file

@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -111,6 +112,7 @@ export interface ServerParsedArgs { @@ -112,6 +113,7 @@ export interface ServerParsedArgs {
'disable-file-uploads'?: boolean; 'disable-file-uploads'?: boolean;
'disable-getting-started-override'?: boolean, 'disable-getting-started-override'?: boolean,
'locale'?: string 'locale'?: string

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.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/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 { export interface IProductConfiguration {
readonly codeServerVersion?: string readonly codeServerVersion?: string
readonly rootEndpoint?: string readonly rootEndpoint?: string
@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */ /* ----- server setup ----- */
@@ -97,6 +99,8 @@ export const serverOptions: OptionDescri @@ -98,6 +100,8 @@ export const serverOptions: OptionDescri
}; };
export interface ServerParsedArgs { export interface ServerParsedArgs {

View file

@ -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-gEAyFzmkyqMoTTnN+3KReFUYoHsK4RAJEb+6eiul+UY=' '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-Oi71Tq4Buohx0KDH3yEbVJUzABnqYv9iVLo420HZXqI=' '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 --> <!-- Disable pinch zooming -->
<meta name="viewport" <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') ?? ''}`); 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 => { .then(async registration => {
/** /**
* @param {MessageEvent} event * @param {MessageEvent} event
@@ -351,6 +351,12 @@ @@ -370,6 +370,12 @@
const hostname = location.hostname; const hostname = location.hostname;

View file

@ -15,7 +15,8 @@ body {
color: #111; color: #111;
color: light-dark(#111, #ddd); color: light-dark(#111, #ddd);
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol"; "Segoe UI Emoji", "Segoe UI Symbol";
overflow: hidden; overflow: hidden;
} }

View file

@ -94,6 +94,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"welcome-text"?: string "welcome-text"?: string
"abs-proxy-base-path"?: string "abs-proxy-base-path"?: string
i18n?: string i18n?: string
"idle-timeout-seconds"?: number
/* Positional arguments. */ /* Positional arguments. */
_?: string[] _?: string[]
} }
@ -303,6 +304,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
path: true, path: true,
description: "Path to JSON file with custom translations. Merges with default strings and supports all i18n keys.", 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[] => { 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") 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] const option = options[key]
if (option.type === "boolean") { if (option.type === "boolean") {
;(args[key] as boolean) = true ;(args[key] as boolean) = true
@ -611,6 +620,16 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["github-auth"] = process.env.GITHUB_TOKEN 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. // Ensure they're not readable by child processes.
delete process.env.PASSWORD delete process.env.PASSWORD
delete process.env.HASHED_PASSWORD delete process.env.HASHED_PASSWORD

View file

@ -1,5 +1,6 @@
import { logger } from "@coder/logger" import { logger } from "@coder/logger"
import { promises as fs } from "fs" import { promises as fs } from "fs"
import { Emitter } from "../common/emitter"
/** /**
* Provides a heartbeat using a local file to indicate activity. * Provides a heartbeat using a local file to indicate activity.
@ -8,6 +9,9 @@ export class Heart {
private heartbeatTimer?: NodeJS.Timeout private heartbeatTimer?: NodeJS.Timeout
private heartbeatInterval = 60000 private heartbeatInterval = 60000
public lastHeartbeat = 0 public lastHeartbeat = 0
private readonly _onChange = new Emitter<"alive" | "expired" | "unknown">()
readonly onChange = this._onChange.event
private state: "alive" | "expired" | "unknown" = "expired"
public constructor( public constructor(
private readonly heartbeatPath: string, private readonly heartbeatPath: string,
@ -17,6 +21,13 @@ export class Heart {
this.alive = this.alive.bind(this) 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 { public alive(): boolean {
const now = Date.now() const now = Date.now()
return now - this.lastHeartbeat < this.heartbeatInterval return now - this.lastHeartbeat < this.heartbeatInterval
@ -28,6 +39,7 @@ export class Heart {
*/ */
public async beat(): Promise<void> { public async beat(): Promise<void> {
if (this.alive()) { if (this.alive()) {
this.setState("alive")
return return
} }
@ -36,7 +48,22 @@ export class Heart {
if (typeof this.heartbeatTimer !== "undefined") { if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer) 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 { try {
return await fs.writeFile(this.heartbeatPath, "") return await fs.writeFile(this.heartbeatPath, "")
} catch (error: any) { } 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

@ -1,9 +1,8 @@
import { field, logger } from "@coder/logger" import { field, logger } from "@coder/logger"
import * as express from "express" import * as express from "express"
import * as expressCore from "express-serve-static-core"
import * as http from "http" import * as http from "http"
import * as net from "net" import * as net from "net"
import * as qs from "qs" import qs from "qs"
import { Disposable } from "../common/emitter" import { Disposable } from "../common/emitter"
import { CookieKeys, HttpCode, HttpError } from "../common/http" import { CookieKeys, HttpCode, HttpError } from "../common/http"
import { normalize } from "../common/util" import { normalize } from "../common/util"
@ -185,12 +184,7 @@ export const constructRedirectPath = (req: express.Request, query: qs.ParsedQs,
* preserved. `to` should be a simple path without any query parameters * preserved. `to` should be a simple path without any query parameters
* `override` will merge with the existing query (use `undefined` to unset). * `override` will merge with the existing query (use `undefined` to unset).
*/ */
export const redirect = ( export const redirect = (req: express.Request, res: express.Response, to: string, override: qs.ParsedQs = {}): void => {
req: express.Request,
res: express.Response,
to: string,
override: expressCore.Query = {},
): void => {
const query = Object.assign({}, req.query, override) const query = Object.assign({}, req.query, override)
Object.keys(override).forEach((key) => { Object.keys(override).forEach((key) => {
if (typeof override[key] === "undefined") { if (typeof override[key] === "undefined") {

View file

@ -11,6 +11,7 @@ import { loadCustomStrings } from "./i18n"
import { register } from "./routes" import { register } from "./routes"
import { VSCodeModule } from "./routes/vscode" import { VSCodeModule } from "./routes/vscode"
import { isDirectory, open } from "./util" import { isDirectory, open } from "./util"
import { wrapper } from "./wrapper"
/** /**
* Return true if the user passed an extension-related VS Code flag. * 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 app = await createApp(args)
const protocol = args.cert ? "https" : "http" const protocol = args.cert ? "https" : "http"
const serverAddress = ensureAddress(app.server, protocol) 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(`Using config file ${args.config}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`) logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
@ -166,6 +167,27 @@ export const runCodeServer = async (
logger.info(" - Not serving HTTPS") 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"]) { if (args["disable-proxy"]) {
logger.info(" - Proxy disabled") logger.info(" - Proxy disabled")
} else if (args["proxy-domain"].length > 0) { } else if (args["proxy-domain"].length > 0) {

View file

@ -28,7 +28,10 @@ import * as vscode from "./vscode"
/** /**
* Register all routes and middleware. * 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 () => { const heart = new Heart(path.join(paths.data, "heartbeat"), async () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// getConnections appears to not call the callback when there are no more // 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.router.use(errorHandler)
app.wsRouter.use(wsErrorHandler) app.wsRouter.use(wsErrorHandler)
return () => { return {
disposeRoutes: () => {
heart.dispose() heart.dispose()
vscode.dispose() vscode.dispose()
},
heart,
} }
} }

View file

@ -1,5 +1,5 @@
import { logger } from "@coder/logger" import { logger } from "@coder/logger"
import { Query } from "express-serve-static-core" import type { ParsedQs } from "qs"
import { promises as fs } from "fs" import { promises as fs } from "fs"
export type Settings = { [key: string]: Settings | string | boolean | number } export type Settings = { [key: string]: Settings | string | boolean | number }
@ -52,5 +52,5 @@ export interface UpdateSettings {
* Global code-server settings. * Global code-server settings.
*/ */
export interface CoderSettings extends UpdateSettings { export interface CoderSettings extends UpdateSettings {
query?: Query query?: ParsedQs
} }

View file

@ -2,8 +2,9 @@ import { logger } from "@coder/logger"
import express from "express" import express from "express"
import * as http from "http" import * as http from "http"
import * as path from "path" import * as path from "path"
import { HttpCode } from "../common/http" import { HttpCode, HttpError } from "../common/http"
import { listen } from "./app" import { listen } from "./app"
import { errorHandler } from "./routes/errors"
import { canConnect } from "./util" import { canConnect } from "./util"
export interface EditorSessionEntry { export interface EditorSessionEntry {
@ -44,24 +45,18 @@ export async function makeEditorSessionManagerServer(
async (req, res) => { async (req, res) => {
const filePath = req.query.filePath const filePath = req.query.filePath
if (!filePath) { if (!filePath) {
res.status(HttpCode.BadRequest).send("filePath is required") throw new HttpError("filePath is required", HttpCode.BadRequest)
return
} }
try {
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath) const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath } const response: GetSessionResponse = { socketPath }
res.json(response) res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
}
}, },
) )
router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => { router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => {
const entry = req.body?.entry const entry = req.body?.entry
if (!entry) { if (!entry) {
res.status(400).send("entry is required") throw new HttpError("entry is required", HttpCode.BadRequest)
return
} }
editorSessionManager.addSession(entry) editorSessionManager.addSession(entry)
res.status(200).send("session added") res.status(200).send("session added")
@ -70,13 +65,14 @@ export async function makeEditorSessionManagerServer(
router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => { router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => {
const socketPath = req.body?.socketPath const socketPath = req.body?.socketPath
if (!socketPath) { if (!socketPath) {
res.status(400).send("socketPath is required") throw new HttpError("socketPath is required", HttpCode.BadRequest)
return
} }
editorSessionManager.deleteSession(socketPath) editorSessionManager.deleteSession(socketPath)
res.status(200).send("session deleted") res.status(200).send("session deleted")
}) })
router.use(errorHandler)
const server = http.createServer(router) const server = http.createServer(router)
try { try {
await listen(server, { socket: codeServerSocketPath }) await listen(server, { socket: codeServerSocketPath })

447
test/package-lock.json generated
View file

@ -7,11 +7,10 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@jest-mock/express": "^1.4.5", "@jest-mock/express": "^1.4.5",
"@playwright/test": "^1.46.0", "@playwright/test": "^1.56.1",
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.13", "@types/jsdom": "^16.2.13",
"@types/node-fetch": "^2.5.8", "@types/node-fetch": "^2.5.8",
"@types/supertest": "^2.0.11",
"@types/wtfnode": "^0.7.0", "@types/wtfnode": "^0.7.0",
"argon2": "^0.28.0", "argon2": "^0.28.0",
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
@ -19,8 +18,7 @@
"jest-fetch-mock": "^3.0.3", "jest-fetch-mock": "^3.0.3",
"jsdom": "^16.4.0", "jsdom": "^16.4.0",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.7",
"playwright": "^1.46.0", "playwright": "^1.56.1",
"supertest": "^6.1.6",
"ts-jest": "^27.0.7", "ts-jest": "^27.0.7",
"wtfnode": "^0.9.1" "wtfnode": "^0.9.1"
} }
@ -1014,13 +1012,13 @@
} }
}, },
"node_modules/@playwright/test": { "node_modules/@playwright/test": {
"version": "1.47.2", "version": "1.56.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz",
"integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==", "integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright": "1.47.2" "playwright": "1.56.1"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@ -1104,13 +1102,6 @@
"@babel/types": "^7.20.7" "@babel/types": "^7.20.7"
} }
}, },
"node_modules/@types/cookiejar": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
"integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/graceful-fs": { "node_modules/@types/graceful-fs": {
"version": "4.1.9", "version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@ -1171,13 +1162,6 @@
"@types/tough-cookie": "*" "@types/tough-cookie": "*"
} }
}, },
"node_modules/@types/methods": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
"integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.7.4", "version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
@ -1220,29 +1204,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/superagent": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
"integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/cookiejar": "^2.1.5",
"@types/methods": "^1.1.4",
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@types/supertest": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.16.tgz",
"integrity": "sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/superagent": "*"
}
},
"node_modules/@types/tough-cookie": { "node_modules/@types/tough-cookie": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
@ -1464,13 +1425,6 @@
"sprintf-js": "~1.0.2" "sprintf-js": "~1.0.2"
} }
}, },
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true,
"license": "MIT"
},
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -1689,24 +1643,18 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/call-bind": { "node_modules/call-bind-apply-helpers": {
"version": "1.0.7", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
"function-bind": "^1.1.2", "function-bind": "^1.1.2"
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/callsites": { "node_modules/callsites": {
@ -1883,16 +1831,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -1914,13 +1852,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/cookiejar": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
"dev": true,
"license": "MIT"
},
"node_modules/cross-fetch": { "node_modules/cross-fetch": {
"version": "3.1.8", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
@ -2030,24 +1961,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -2085,17 +1998,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/dezalgo": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
"dev": true,
"license": "ISC",
"dependencies": {
"asap": "^2.0.0",
"wrappy": "1"
}
},
"node_modules/diff-sequences": { "node_modules/diff-sequences": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
@ -2130,6 +2032,21 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.32", "version": "1.5.32",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz",
@ -2178,14 +2095,11 @@
} }
}, },
"node_modules/es-define-property": { "node_modules/es-define-property": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
} }
@ -2200,6 +2114,35 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@ -2366,13 +2309,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-safe-stringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
"dev": true,
"license": "MIT"
},
"node_modules/fb-watchman": { "node_modules/fb-watchman": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
@ -2421,36 +2357,22 @@
} }
}, },
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.0", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
}, },
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/formidable": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
"integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"dezalgo": "^1.0.4",
"hexoid": "^1.0.0",
"once": "^1.4.0",
"qs": "^6.11.0"
},
"funding": {
"url": "https://ko-fi.com/tunnckoCore/commissions"
}
},
"node_modules/fs-minipass": { "node_modules/fs-minipass": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@ -2559,17 +2481,22 @@
} }
}, },
"node_modules/get-intrinsic": { "node_modules/get-intrinsic": {
"version": "1.2.4", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2", "function-bind": "^1.1.2",
"has-proto": "^1.0.1", "get-proto": "^1.0.1",
"has-symbols": "^1.0.3", "gopd": "^1.2.0",
"hasown": "^2.0.0" "has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -2588,6 +2515,20 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": { "node_modules/get-stream": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
@ -2637,13 +2578,13 @@
} }
}, },
"node_modules/gopd": { "node_modules/gopd": {
"version": "1.0.1", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "engines": {
"get-intrinsic": "^1.1.3" "node": ">= 0.4"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@ -2666,23 +2607,10 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/has-property-descriptors": { "node_modules/has-symbols": {
"version": "1.0.2", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -2692,12 +2620,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-symbols": { "node_modules/has-tostringtag": {
"version": "1.0.3", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
}, },
@ -2725,16 +2656,6 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/hexoid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/html-encoding-sniffer": { "node_modules/html-encoding-sniffer": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@ -3764,15 +3685,17 @@
} }
}, },
"node_modules/jsdom/node_modules/form-data": { "node_modules/jsdom/node_modules/form-data": {
"version": "3.0.1", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"mime-types": "^2.1.12" "es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.35"
}, },
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
@ -3918,6 +3841,16 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -3925,16 +3858,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/micromatch": { "node_modules/micromatch": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@ -3949,19 +3872,6 @@
"node": ">=8.6" "node": ">=8.6"
} }
}, },
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@ -4216,19 +4126,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/once": { "node_modules/once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -4408,13 +4305,13 @@
} }
}, },
"node_modules/playwright": { "node_modules/playwright": {
"version": "1.47.2", "version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz",
"integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==", "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"playwright-core": "1.47.2" "playwright-core": "1.56.1"
}, },
"bin": { "bin": {
"playwright": "cli.js" "playwright": "cli.js"
@ -4427,9 +4324,9 @@
} }
}, },
"node_modules/playwright-core": { "node_modules/playwright-core": {
"version": "1.47.2", "version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz",
"integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==", "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@ -4531,22 +4428,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/querystringify": { "node_modules/querystringify": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@ -4722,24 +4603,6 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -4763,25 +4626,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "3.0.7", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@ -4932,43 +4776,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/superagent": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz",
"integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
"deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net",
"dev": true,
"license": "MIT",
"dependencies": {
"component-emitter": "^1.3.0",
"cookiejar": "^2.1.4",
"debug": "^4.3.4",
"fast-safe-stringify": "^2.1.1",
"form-data": "^4.0.0",
"formidable": "^2.1.2",
"methods": "^1.1.2",
"mime": "2.6.0",
"qs": "^6.11.0",
"semver": "^7.3.8"
},
"engines": {
"node": ">=6.4.0 <13 || >=14"
}
},
"node_modules/supertest": {
"version": "6.3.4",
"resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz",
"integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==",
"dev": true,
"license": "MIT",
"dependencies": {
"methods": "^1.1.2",
"superagent": "^8.1.2"
},
"engines": {
"node": ">=6.4.0"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View file

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

View file

@ -1,6 +1,6 @@
import { logger } from "@coder/logger" import { logger } from "@coder/logger"
import { readFile, writeFile, stat, utimes } from "fs/promises" 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" import { clean, mockLogger, tmpdir } from "../../utils/helpers"
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo) const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
@ -82,7 +82,52 @@ describe("Heart", () => {
}) })
describe("heartbeatTimer", () => { 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() mockLogger()
}) })
afterAll(() => { afterAll(() => {
@ -90,23 +135,28 @@ describe("heartbeatTimer", () => {
}) })
afterEach(() => { afterEach(() => {
jest.resetAllMocks() jest.resetAllMocks()
if (heart) {
heart.dispose()
}
}) })
it("should call beat when isActive resolves to true", async () => { it("should change to alive after a beat", async () => {
const isActive = true heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
const mockIsActive = jest.fn().mockResolvedValue(isActive) const mockOnChange = jest.fn()
const mockBeatFn = jest.fn() heart.onChange(mockOnChange)
await heartbeatTimer(mockIsActive, mockBeatFn) await heart.beat()
expect(mockIsActive).toHaveBeenCalled()
expect(mockBeatFn).toHaveBeenCalled() expect(mockOnChange.mock.calls[0][0]).toBe("alive")
}) })
it("should log a warning when isActive rejects", async () => { it.only("should change to expired when not active", async () => {
const errorMsg = "oh no" jest.useFakeTimers()
const error = new Error(errorMsg) heart = new Heart(`${testDir}/shutdown.txt`, () => new Promise((resolve) => resolve(false)))
const mockIsActive = jest.fn().mockRejectedValue(error) const mockOnChange = jest.fn()
const mockBeatFn = jest.fn() heart.onChange(mockOnChange)
await heartbeatTimer(mockIsActive, mockBeatFn) await heart.beat()
expect(mockIsActive).toHaveBeenCalled()
expect(mockBeatFn).not.toHaveBeenCalled() await jest.advanceTimersByTime(60 * 1000)
expect(logger.warn).toHaveBeenCalledWith(errorMsg) 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(), debug: jest.fn(),
warn: jest.fn(), warn: jest.fn(),
error: jest.fn(), error: jest.fn(),
named: jest.fn(),
level: 0, level: 0,
}, },
field: jest.fn(), field: jest.fn(),
@ -94,7 +95,7 @@ describe("main", () => {
// Mock routes module // Mock routes module
jest.doMock("../../../src/node/routes", () => ({ jest.doMock("../../../src/node/routes", () => ({
register: jest.fn().mockResolvedValue(jest.fn()), register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
})) }))
// Mock loadCustomStrings to succeed // Mock loadCustomStrings to succeed
@ -131,7 +132,7 @@ describe("main", () => {
// Mock routes module // Mock routes module
jest.doMock("../../../src/node/routes", () => ({ jest.doMock("../../../src/node/routes", () => ({
register: jest.fn().mockResolvedValue(jest.fn()), register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
})) }))
// Import runCodeServer after mocking // Import runCodeServer after mocking