mirror of
https://github.com/coder/code-server.git
synced 2026-02-05 22:38:40 -06:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e90504b8cf | ||
|
|
3c0b449c6e | ||
|
|
7f2112c1c9 | ||
|
|
7ec0be6995 | ||
|
|
1dd0741c94 | ||
|
|
aa210cdad4 | ||
|
|
9e97cd1278 | ||
|
|
352636408c | ||
|
|
f223d301a2 | ||
|
|
809abfbbe0 | ||
|
|
f5dc5436da | ||
|
|
94a533e540 | ||
|
|
ba588b4709 | ||
|
|
3368ef91ef | ||
|
|
65d6b9a4c4 | ||
|
|
e352745c4c | ||
|
|
9233f04383 | ||
|
|
8c077bf605 | ||
|
|
41f7ba903f | ||
|
|
ac7322ce56 | ||
|
|
68ac95b84e | ||
|
|
0de7cf5679 | ||
|
|
ea9a3a5ab2 | ||
|
|
472bf8a5fa | ||
|
|
eccb1eb537 | ||
|
|
f128a7ac11 | ||
|
|
80996d2e08 | ||
|
|
9819b91c74 | ||
|
|
2ed1098c1e | ||
|
|
85042e2910 | ||
|
|
904942a194 | ||
|
|
9a24e467b2 | ||
|
|
24a777491b | ||
|
|
93c1f4f10c | ||
|
|
339c3926c2 | ||
|
|
897b5f13bc | ||
|
|
282f74d9f5 | ||
|
|
7a2a5eb055 | ||
|
|
af397f71e2 | ||
|
|
9d89b17fd7 | ||
|
|
35e7b09a85 | ||
|
|
7beb05d04f | ||
|
|
add51d5c5b | ||
|
|
db8a41bce1 | ||
|
|
811ec6c1d6 | ||
|
|
30321abfcd | ||
|
|
cd40509fbb | ||
|
|
9fd98d58e7 | ||
|
|
b0992ddb3e | ||
|
|
af19dedfa9 | ||
|
|
d1066af558 | ||
|
|
ba774d989b | ||
|
|
1a7b770f5b | ||
|
|
626145cf66 | ||
|
|
b59a4f7366 | ||
|
|
54b33a75e0 | ||
|
|
3c5deac16d | ||
|
|
fbaadbcfbc | ||
|
|
2bbb6e8cca | ||
|
|
f1236d80b9 | ||
|
|
b27d982c67 | ||
|
|
3f23840756 | ||
|
|
e54467fb85 | ||
|
|
8f738d29f2 | ||
|
|
5c0ff5013f | ||
|
|
8a378df6e5 | ||
|
|
a7e77ce4af | ||
|
|
794def9a77 | ||
|
|
b5a2ce2522 | ||
|
|
bc15fa461c | ||
|
|
1805daed07 | ||
|
|
6f3d0a7e5a | ||
|
|
b1ad6ffcb9 |
12
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
12
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -86,6 +86,18 @@ body:
|
||||
validations:
|
||||
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` (this is not the same as vscode.dev).
|
||||
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
|
||||
attributes:
|
||||
label: Does this bug reproduce in GitHub Codespaces?
|
||||
|
||||
44
.github/workflows/build.yaml
vendored
44
.github/workflows/build.yaml
vendored
@ -32,7 +32,7 @@ jobs:
|
||||
helm: ${{ steps.filter.outputs.helm }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Check changed files
|
||||
uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
@ -64,8 +64,8 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -82,8 +82,8 @@ jobs:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.docs == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.helm == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: azure/setup-helm@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -114,8 +114,8 @@ jobs:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.code == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -132,11 +132,11 @@ jobs:
|
||||
if: needs.changes.outputs.ci == 'true'
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Check workflow files
|
||||
run: |
|
||||
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.1
|
||||
./actionlint -color -shellcheck= -ignore "set-output"
|
||||
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.9
|
||||
./actionlint -color -shellcheck= -ignore "softprops/action-gh-release"
|
||||
shell: bash
|
||||
|
||||
test-unit:
|
||||
@ -146,8 +146,8 @@ jobs:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.code == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -164,12 +164,12 @@ jobs:
|
||||
build:
|
||||
name: Build code-server
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 70
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
DISABLE_V8_COMPILE_CACHE: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: true
|
||||
- run: sudo apt update && sudo apt install -y libkrb5-dev
|
||||
@ -178,7 +178,7 @@ jobs:
|
||||
packages: quilt
|
||||
version: 1.0
|
||||
- run: quilt push -a
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -231,9 +231,9 @@ jobs:
|
||||
needs: [changes, build]
|
||||
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- run: sudo apt update && sudo apt install -y libkrb5-dev
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -241,7 +241,7 @@ jobs:
|
||||
package-lock.json
|
||||
test/package-lock.json
|
||||
- run: SKIP_SUBMODULE_DEPS=1 npm ci
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-package
|
||||
- run: tar -xzf package.tar.gz
|
||||
@ -265,9 +265,9 @@ jobs:
|
||||
needs: [changes, build]
|
||||
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.deps == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- run: sudo apt update && sudo apt install -y libkrb5-dev
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -275,7 +275,7 @@ jobs:
|
||||
package-lock.json
|
||||
test/package-lock.json
|
||||
- run: SKIP_SUBMODULE_DEPS=1 npm ci
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-package
|
||||
- run: tar -xzf package.tar.gz
|
||||
|
||||
6
.github/workflows/installer.yaml
vendored
6
.github/workflows/installer.yaml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install code-server
|
||||
run: ./install.sh
|
||||
@ -44,7 +44,7 @@ jobs:
|
||||
container: "alpine:3.17"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install curl
|
||||
run: apk add curl
|
||||
@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install code-server
|
||||
run: ./install.sh
|
||||
|
||||
42
.github/workflows/publish.yaml
vendored
42
.github/workflows/publish.yaml
vendored
@ -25,10 +25,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
|
||||
@ -53,38 +53,6 @@ jobs:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
@ -94,13 +62,13 @@ jobs:
|
||||
steps:
|
||||
# We need to checkout code-server so we can get the version
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: "./code-server"
|
||||
|
||||
- name: Checkout code-server-aur repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: "cdrci/code-server-aur"
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
||||
@ -148,7 +116,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code-server
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
24
.github/workflows/release.yaml
vendored
24
.github/workflows/release.yaml
vendored
@ -60,10 +60,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -94,7 +94,7 @@ jobs:
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-release-package
|
||||
|
||||
@ -126,7 +126,7 @@ jobs:
|
||||
|
||||
package-macos-amd64:
|
||||
name: x86-64 macOS build
|
||||
runs-on: macos-13
|
||||
runs-on: macos-15-intel
|
||||
timeout-minutes: 15
|
||||
needs: npm-version
|
||||
env:
|
||||
@ -134,10 +134,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -160,7 +160,7 @@ jobs:
|
||||
- run: brew install python-setuptools
|
||||
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-release-package
|
||||
|
||||
@ -195,10 +195,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
cache: npm
|
||||
@ -221,7 +221,7 @@ jobs:
|
||||
- run: brew install python-setuptools
|
||||
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-release-package
|
||||
|
||||
@ -253,7 +253,7 @@ jobs:
|
||||
needs: npm-version
|
||||
steps:
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: npm-release-package
|
||||
|
||||
@ -269,7 +269,7 @@ jobs:
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: dawidd6/action-download-artifact@v10
|
||||
uses: dawidd6/action-download-artifact@v12
|
||||
id: download
|
||||
with:
|
||||
branch: ${{ github.ref }}
|
||||
|
||||
4
.github/workflows/scripts.yaml
vendored
4
.github/workflows/scripts.yaml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
container: "alpine:3.17"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install test utilities
|
||||
run: apk add bats checkbashisms
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install lint utilities
|
||||
run: sudo apt install shellcheck
|
||||
|
||||
18
.github/workflows/security.yaml
vendored
18
.github/workflows/security.yaml
vendored
@ -25,12 +25,12 @@ jobs:
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .node-version
|
||||
|
||||
@ -46,12 +46,12 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
@ -62,7 +62,7 @@ jobs:
|
||||
severity: "HIGH,CRITICAL"
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: "trivy-repo-results.sarif"
|
||||
|
||||
@ -76,17 +76,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
config-file: ./.github/codeql-config.yml
|
||||
languages: javascript
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
uses: github/codeql-action/autobuild@v4
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v4
|
||||
|
||||
6
.github/workflows/trivy-docker.yaml
vendored
6
.github/workflows/trivy-docker.yaml
vendored
@ -48,10 +48,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run Trivy vulnerability scanner in image mode
|
||||
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
|
||||
with:
|
||||
image-ref: "docker.io/codercom/code-server:latest"
|
||||
ignore-unfixed: true
|
||||
@ -60,6 +60,6 @@ jobs:
|
||||
severity: "HIGH,CRITICAL"
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: "trivy-image-results.sarif"
|
||||
|
||||
@ -1 +1 @@
|
||||
22.15.1
|
||||
22.21.1
|
||||
|
||||
143
CHANGELOG.md
143
CHANGELOG.md
@ -22,6 +22,148 @@ Code v99.99.999
|
||||
|
||||
## Unreleased
|
||||
|
||||
## [4.108.0](https://github.com/coder/code-server/releases/tag/v4.108.0) - 2026-01-12
|
||||
|
||||
Code v1.108.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.108.0
|
||||
|
||||
## [4.107.1](https://github.com/coder/code-server/releases/tag/v4.107.1) - 2026-01-09
|
||||
|
||||
Code v1.107.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.107.1
|
||||
|
||||
## [4.107.0](https://github.com/coder/code-server/releases/tag/v4.107.0) - 2026-12-17
|
||||
|
||||
Code v1.107.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.107.0
|
||||
|
||||
### Added
|
||||
|
||||
- New `--cookie-suffix` flag that can be used to add a suffix to the cookie when
|
||||
using the built-in password authentication. You can use this to avoid
|
||||
collisions with other instances of code-server.
|
||||
- Support a new property `authorizationHeaderToken` on the extension gallery
|
||||
configuration. This will be added to marketplace requests as a bearer token
|
||||
using the `Authorization` header.
|
||||
|
||||
## [4.106.3](https://github.com/coder/code-server/releases/tag/v4.106.3) - 2025-12-01
|
||||
|
||||
Code v1.106.3
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.106.3
|
||||
|
||||
## [4.106.2](https://github.com/coder/code-server/releases/tag/v4.106.2) - 2025-11-19
|
||||
|
||||
Code v1.106.2
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.106.2
|
||||
|
||||
## [4.106.0](https://github.com/coder/code-server/releases/tag/v4.106.0) - 2025-11-19
|
||||
|
||||
Code v1.106.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.106.0
|
||||
|
||||
## [4.105.1](https://github.com/coder/code-server/releases/tag/v4.105.1) - 2025-10-20
|
||||
|
||||
Code v1.105.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.105.1
|
||||
|
||||
## [4.105.0](https://github.com/coder/code-server/releases/tag/v4.105.0) - 2025-10-17
|
||||
|
||||
Code v1.105.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.105.0
|
||||
|
||||
## [4.104.3](https://github.com/coder/code-server/releases/tag/v4.104.3) - 2025-10-07
|
||||
|
||||
Code v1.104.3
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to Code 1.104.3.
|
||||
|
||||
## [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
|
||||
|
||||
Code v1.102.1
|
||||
@ -802,7 +944,6 @@ Code v1.68.1
|
||||
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:
|
||||
|
||||
- You run code-server with the built-in password authentication.
|
||||
- You run unprotected HTTP services on ports accessible by code-server.
|
||||
|
||||
|
||||
@ -15,9 +15,9 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 3.29.1
|
||||
version: 3.32.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
appVersion: 4.102.1
|
||||
appVersion: 4.108.0
|
||||
|
||||
@ -3,23 +3,21 @@ kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "code-server.fullname" . }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
{{- if .Values.annotations }}
|
||||
annotations: {{- toYaml .Values.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount | default 1 }}
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- include "code-server.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- include "code-server.selectorLabels" . | nindent 8 }}
|
||||
{{- if .Values.podAnnotations }}
|
||||
annotations: {{- toYaml .Values.podAnnotations | nindent 8 }}
|
||||
{{- end }}
|
||||
@ -127,11 +125,11 @@ spec:
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
path: /healthz
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
path: /healthz
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
|
||||
@ -9,10 +9,7 @@ metadata:
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.accessMode | quote }}
|
||||
|
||||
@ -6,10 +6,7 @@ metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": "pre-install"
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{- if .Values.password }}
|
||||
|
||||
@ -3,10 +3,7 @@ kind: Service
|
||||
metadata:
|
||||
name: {{ include "code-server.fullname" . }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
|
||||
@ -3,9 +3,6 @@ apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
name: {{ template "code-server.serviceAccountName" . }}
|
||||
{{- end -}}
|
||||
|
||||
@ -3,16 +3,13 @@ kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "code-server.fullname" . }}-test-connection"
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "code-server.name" . }}
|
||||
helm.sh/chart: {{ include "code-server.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- include "code-server.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test-success
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "code-server.fullname" . }}:{{ .Values.service.port }}']
|
||||
args: ['{{ include "code-server.fullname" . }}:{{ .Values.service.port }}/healthz']
|
||||
restartPolicy: Never
|
||||
|
||||
@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '4.102.1'
|
||||
tag: '4.108.0'
|
||||
pullPolicy: Always
|
||||
|
||||
# Specifies one or more secrets to be used when pulling images from a
|
||||
@ -31,6 +31,9 @@ serviceAccount:
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
# Specifies annotations for deployment
|
||||
annotations: {}
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
17
docs/FAQ.md
17
docs/FAQ.md
@ -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 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 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)
|
||||
- [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)
|
||||
@ -322,12 +323,8 @@ As long as there is an active browser connection, code-server touches
|
||||
`~/.local/share/code-server/heartbeat` once a minute.
|
||||
|
||||
If you want to shutdown code-server if there hasn't been an active connection
|
||||
after a predetermined amount of time, you can do so by checking continuously for
|
||||
the last modified time on the heartbeat file. If it is older than X minutes (or
|
||||
whatever amount of time you'd like), you can kill code-server.
|
||||
|
||||
Eventually, [#1636](https://github.com/coder/code-server/issues/1636) will make
|
||||
this process better.
|
||||
after a predetermined amount of time, you can use the --idle-timeout-seconds flag
|
||||
or set an `CODE_SERVER_IDLE_TIMEOUT_SECONDS` environment variable.
|
||||
|
||||
## How do I change the password?
|
||||
|
||||
@ -443,6 +440,8 @@ Specific changes include:
|
||||
- The ability to use your own marketplace and collect your own telemetry
|
||||
- Built-in proxy for accessing ports on the remote machine integrated into
|
||||
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
|
||||
- Notification when updates are available
|
||||
- [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
|
||||
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?
|
||||
|
||||
code-server supports setting a single password and limits logins to two per
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# code-server
|
||||
|
||||
[](https://github.com/coder/code-server/discussions) [](https://coder.com/community) [](https://twitter.com/coderhq) [](https://codecov.io/gh/coder/code-server) [](https://coder.com/docs/code-server/latest)
|
||||
[](https://github.com/coder/code-server/discussions) [](https://coder.com/community) [](https://twitter.com/coderhq) [](https://discord.com/invite/coder) [](https://codecov.io/gh/coder/code-server) [](https://coder.com/docs/code-server/latest)
|
||||
|
||||
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
|
||||
access it in the browser.
|
||||
|
||||
@ -14,8 +14,8 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
||||
7. Install and use Node.js 22:
|
||||
|
||||
```shell
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
nvm install 22
|
||||
nvm use 22
|
||||
```
|
||||
|
||||
8. Install code-server globally on device with: `npm install --global code-server`
|
||||
|
||||
@ -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 any unrecognized Linux operating system, code-server will install the
|
||||
latest standalone release into `~/.local`.
|
||||
|
||||
- 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
|
||||
Homebrew installed, code-server will install the latest standalone release
|
||||
into `~/.local`).
|
||||
|
||||
- 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`
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit c306e94f98122556ca081f527b466015e1bc37b0
|
||||
Subproject commit c9d77990917f3102ada88be140d28b038d1dd7c7
|
||||
1526
package-lock.json
generated
1526
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -57,19 +57,19 @@
|
||||
"doctoc": "^2.2.1",
|
||||
"eslint": "^9.12.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-prettier": "^5.0.0",
|
||||
"globals": "^16.1.0",
|
||||
"prettier": "3.4.2",
|
||||
"prettier-plugin-sh": "^0.14.0",
|
||||
"prettier": "3.6.2",
|
||||
"prettier-plugin-sh": "^0.18.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.6.2",
|
||||
"typescript-eslint": "^8.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coder/logger": "^3.0.1",
|
||||
"argon2": "^0.31.1",
|
||||
"argon2": "^0.44.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"env-paths": "^2.2.1",
|
||||
@ -81,9 +81,8 @@
|
||||
"limiter": "^2.1.0",
|
||||
"pem": "^1.14.8",
|
||||
"proxy-agent": "^6.3.1",
|
||||
"qs": "6.14.0",
|
||||
"qs": "6.14.1",
|
||||
"rotating-file-stream": "^3.1.1",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"safe-compare": "^1.1.4",
|
||||
"semver": "^7.5.4",
|
||||
"ws": "^8.14.2",
|
||||
|
||||
@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/network.ts
|
||||
@@ -223,7 +223,9 @@ class RemoteAuthoritiesImpl {
|
||||
@@ -237,7 +237,9 @@ class RemoteAuthoritiesImpl {
|
||||
return URI.from({
|
||||
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
|
||||
authority: `${host}:${port}`,
|
||||
@ -99,14 +99,14 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactor
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
|
||||
@@ -281,6 +281,7 @@ export class BrowserSocketFactory implem
|
||||
@@ -282,6 +282,7 @@ export class BrowserSocketFactory implem
|
||||
connect({ host, port }: WebSocketRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
|
||||
return new Promise<ISocket>((resolve, reject) => {
|
||||
const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws');
|
||||
+ path = (mainWindow.location.pathname + "/" + path).replace(/\/\/+/g, "/")
|
||||
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
|
||||
const errorListener = socket.onError(reject);
|
||||
socket.onOpen(() => {
|
||||
const disposables = new DisposableStore();
|
||||
disposables.add(socket.onError(reject));
|
||||
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@ -241,7 +241,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -57,6 +57,7 @@ export type ExtensionVirtualWorkspaceSup
|
||||
@@ -66,6 +66,7 @@ export type ExtensionVirtualWorkspaceSup
|
||||
|
||||
export interface IProductConfiguration {
|
||||
readonly codeServerVersion?: string
|
||||
@ -253,7 +253,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
@@ -333,7 +333,8 @@ class LocalStorageURLCallbackProvider ex
|
||||
@@ -339,7 +339,8 @@ class LocalStorageURLCallbackProvider ex
|
||||
this.startListening();
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
}
|
||||
|
||||
private startListening(): void {
|
||||
@@ -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 () {
|
||||
|
||||
// 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) {
|
||||
throw new Error('Missing web configuration element');
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
@@ -106,10 +106,14 @@ class RemoteTerminalBackend extends Base
|
||||
@@ -107,10 +107,14 @@ class RemoteTerminalBackend extends Base
|
||||
}
|
||||
const reqId = e.reqId;
|
||||
const commandId = e.commandId;
|
||||
|
||||
@ -65,7 +65,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
|
||||
@@ -97,7 +97,7 @@ class RemoteTerminalBackend extends Base
|
||||
@@ -98,7 +98,7 @@ class RemoteTerminalBackend extends Base
|
||||
}
|
||||
});
|
||||
|
||||
@ -78,7 +78,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
|
||||
@@ -134,6 +134,7 @@ export interface NativeParsedArgs {
|
||||
@@ -137,6 +137,7 @@ export interface NativeParsedArgs {
|
||||
'disable-chromium-sandbox'?: boolean;
|
||||
sandbox?: boolean;
|
||||
'enable-coi'?: boolean;
|
||||
@ -90,7 +90,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
|
||||
@@ -104,6 +104,7 @@ export const OPTIONS: OptionDescriptions
|
||||
@@ -105,6 +105,7 @@ export const OPTIONS: OptionDescriptions
|
||||
'user-data-dir': { type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") },
|
||||
'profile': { type: 'string', 'cat': 'o', args: 'profileName', description: localize('profileName', "Opens the provided folder or workspace with the given profile and associates the profile with the workspace. If the profile does not exist, a new empty one is created.") },
|
||||
'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },
|
||||
@ -110,7 +110,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -295,6 +296,22 @@ export async function main(desc: Product
|
||||
@@ -300,6 +301,22 @@ export async function main(desc: Product
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -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/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') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -11,14 +11,14 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
@@ -12,7 +12,7 @@ import * as path from '../../base/common
|
||||
import { IURITransformer } from '../../base/common/uriIpc.js';
|
||||
import { getMachineId, getSqmMachineId, getdevDeviceId } from '../../base/node/id.js';
|
||||
import { getMachineId, getSqmMachineId, getDevDeviceId } from '../../base/node/id.js';
|
||||
import { Promises } from '../../base/node/pfs.js';
|
||||
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
|
||||
+import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from '../../base/parts/ipc/common/ipc.js';
|
||||
import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
import { ConfigurationService } from '../../platform/configuration/common/configurationService.js';
|
||||
@@ -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)));
|
||||
|
||||
@ -190,7 +190,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -21,6 +21,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -22,6 +22,7 @@ export const serverOptions: OptionDescri
|
||||
'disable-file-downloads': { type: 'boolean' },
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
'disable-getting-started-override': { type: 'boolean' },
|
||||
@ -198,7 +198,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -109,6 +110,7 @@ export interface ServerParsedArgs {
|
||||
@@ -113,6 +114,7 @@ export interface ServerParsedArgs {
|
||||
'disable-file-downloads'?: boolean;
|
||||
'disable-file-uploads'?: boolean;
|
||||
'disable-getting-started-override'?: boolean,
|
||||
@ -272,7 +272,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
|
||||
@@ -475,9 +475,6 @@ export class InstallAction extends Exten
|
||||
@@ -474,9 +474,6 @@ export class InstallAction extends Exten
|
||||
if (this.extension.isBuiltin) {
|
||||
return;
|
||||
}
|
||||
@ -282,7 +282,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
if (this.extension.state !== ExtensionState.Uninstalled) {
|
||||
return;
|
||||
}
|
||||
@@ -782,7 +779,7 @@ export abstract class InstallInOtherServ
|
||||
@@ -781,7 +778,7 @@ export abstract class InstallInOtherServ
|
||||
}
|
||||
|
||||
if (isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
@ -291,7 +291,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
}
|
||||
|
||||
// Prefers to run on UI
|
||||
@@ -2073,17 +2070,6 @@ export class SetLanguageAction extends E
|
||||
@@ -2072,17 +2069,6 @@ export class SetLanguageAction extends E
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
this.class = SetLanguageAction.DisabledClass;
|
||||
@ -309,7 +309,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
}
|
||||
|
||||
override async run(): Promise<any> {
|
||||
@@ -2100,7 +2086,6 @@ export class ClearLanguageAction extends
|
||||
@@ -2099,7 +2085,6 @@ export class ClearLanguageAction extends
|
||||
private static readonly DisabledClass = `${this.EnabledClass} disabled`;
|
||||
|
||||
constructor(
|
||||
@ -317,7 +317,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
|
||||
@ILocaleService private readonly localeService: ILocaleService,
|
||||
) {
|
||||
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
|
||||
@@ -2110,17 +2095,6 @@ export class ClearLanguageAction extends
|
||||
@@ -2109,17 +2094,6 @@ export class ClearLanguageAction extends
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
this.class = ClearLanguageAction.DisabledClass;
|
||||
@ -339,7 +339,7 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.internal.ts
|
||||
@@ -53,7 +53,7 @@ import './services/dialogs/browser/fileD
|
||||
@@ -54,7 +54,7 @@ import './services/dialogs/browser/fileD
|
||||
import './services/host/browser/browserHostService.js';
|
||||
import './services/lifecycle/browser/lifecycleService.js';
|
||||
import './services/clipboard/browser/clipboardService.js';
|
||||
|
||||
@ -90,7 +90,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -18,6 +18,8 @@ export const serverOptions: OptionDescri
|
||||
@@ -19,6 +19,8 @@ export const serverOptions: OptionDescri
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check': { type: 'boolean' },
|
||||
'auth': { type: 'string' },
|
||||
@ -99,7 +99,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -103,6 +105,8 @@ export interface ServerParsedArgs {
|
||||
@@ -107,6 +109,8 @@ export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
'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/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@@ -7,11 +7,11 @@ import { Event } from '../../base/common
|
||||
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
|
||||
@@ -6,10 +6,10 @@
|
||||
import { Disposable } from '../../base/common/lifecycle.js';
|
||||
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
|
||||
import { IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
-import { IWorkbenchEnvironmentService } from '../services/environment/common/environmentService.js';
|
||||
@ -139,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from '../../platform/workspace/common/workspace.js';
|
||||
import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js';
|
||||
import { getRemoteName } from '../../platform/remote/common/remoteHosts.js';
|
||||
@@ -71,7 +71,7 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -69,7 +69,7 @@ export class WorkbenchContextKeysHandler
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ -148,7 +147,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@@ -200,6 +200,10 @@ export class WorkbenchContextKeysHandler
|
||||
@@ -199,6 +199,10 @@ export class WorkbenchContextKeysHandler
|
||||
this.auxiliaryBarMaximizedContext = AuxiliaryBarMaximizedContext.bindTo(this.contextKeyService);
|
||||
this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized());
|
||||
|
||||
@ -208,9 +207,9 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
@@ -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 IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
|
||||
@ -240,13 +239,14 @@ Index: code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFi
|
||||
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
|
||||
@IPathService protected readonly pathService: IPathService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@@ -310,20 +310,22 @@ export class SimpleFileDialog extends Di
|
||||
this.filePickBox.ignoreFocusOut = true;
|
||||
@@ -311,21 +311,23 @@ export class SimpleFileDialog extends Di
|
||||
this.filePickBox.placeholder = nls.localize('remoteFileDialog.placeholder', "Folder path");
|
||||
this.filePickBox.ok = true;
|
||||
this.filePickBox.okLabel = typeof this.options.openLabel === 'string' ? this.options.openLabel : this.options.openLabel?.withoutMnemonic;
|
||||
- if ((this.scheme !== Schemas.file) && this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) {
|
||||
- this.filePickBox.customButton = true;
|
||||
- this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
|
||||
- this.filePickBox.customButtonSecondary = true;
|
||||
- let action;
|
||||
- if (isSave) {
|
||||
- action = SaveLocalFileCommand;
|
||||
@ -262,6 +262,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFi
|
||||
+ if ((this.scheme !== Schemas.file) && this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) {
|
||||
+ this.filePickBox.customButton = true;
|
||||
+ this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
|
||||
+ this.filePickBox.customButtonSecondary = true;
|
||||
+ let action;
|
||||
+ if (isSave) {
|
||||
+ action = SaveLocalFileCommand;
|
||||
@ -289,7 +290,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
|
||||
import { WorkbenchCompressibleAsyncDataTree } from '../../../../../platform/list/browser/listService.js';
|
||||
import { ISearchService, QueryType, getExcludes, ISearchConfiguration, ISearchComplete, IFileQuery } from '../../../../services/search/common/search.js';
|
||||
import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
||||
@@ -1601,7 +1602,8 @@ export class FileDragAndDrop implements
|
||||
@@ -1597,7 +1598,8 @@ export class FileDragAndDrop implements
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
|
||||
@ -299,7 +300,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explo
|
||||
) {
|
||||
const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => {
|
||||
if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) {
|
||||
@@ -1826,15 +1828,17 @@ export class FileDragAndDrop implements
|
||||
@@ -1822,15 +1824,17 @@ export class FileDragAndDrop implements
|
||||
|
||||
// External file DND (Import/Upload file)
|
||||
if (data instanceof NativeDragAndDropData) {
|
||||
|
||||
@ -17,8 +17,8 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
|
||||
-import { $, Dimension, addDisposableListener, append, clearNode, reset } from '../../../../base/browser/dom.js';
|
||||
+import { $, Dimension, addDisposableListener, append, clearNode, reset, prepend } from '../../../../base/browser/dom.js';
|
||||
import { renderFormattedText } from '../../../../base/browser/formattedTextRenderer.js';
|
||||
import { status } from '../../../../base/browser/ui/aria/aria.js';
|
||||
import { StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
|
||||
import { Button } from '../../../../base/browser/ui/button/button.js';
|
||||
@@ -54,7 +54,7 @@ import { IRecentFolder, IRecentWorkspace
|
||||
import { OpenRecentAction } from '../../../browser/actions/windowActions.js';
|
||||
import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from '../../../browser/actions/workspaceActions.js';
|
||||
@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
|
||||
import { IEditorOpenContext, IEditorSerializer } from '../../../common/editor.js';
|
||||
import { IWebviewElement, IWebviewService } from '../../webview/browser/webview.js';
|
||||
import './gettingStartedColors.js';
|
||||
@@ -876,6 +876,72 @@ export class GettingStartedPage extends
|
||||
@@ -920,6 +920,72 @@ export class GettingStartedPage extends
|
||||
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
|
||||
);
|
||||
|
||||
@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
|
||||
const leftColumn = $('.categories-column.categories-column-left', {},);
|
||||
const rightColumn = $('.categories-column.categories-column-right', {},);
|
||||
|
||||
@@ -911,6 +977,9 @@ export class GettingStartedPage extends
|
||||
@@ -955,6 +1021,9 @@ export class GettingStartedPage extends
|
||||
recentList.setLimit(5);
|
||||
reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
|
||||
}
|
||||
@ -181,7 +181,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -20,6 +20,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -21,6 +21,7 @@ export const serverOptions: OptionDescri
|
||||
'auth': { type: 'string' },
|
||||
'disable-file-downloads': { type: 'boolean' },
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
@ -189,7 +189,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -107,6 +108,7 @@ export interface ServerParsedArgs {
|
||||
@@ -111,6 +112,7 @@ export interface ServerParsedArgs {
|
||||
'auth'?: string;
|
||||
'disable-file-downloads'?: 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/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@@ -7,7 +7,7 @@ import { Event } from '../../base/common
|
||||
import { Disposable, DisposableStore } from '../../base/common/lifecycle.js';
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Disposable } from '../../base/common/lifecycle.js';
|
||||
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
|
||||
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow, isEditableElement } from '../../base/browser/dom.js';
|
||||
import { IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';
|
||||
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads } from '../common/contextkeys.js';
|
||||
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from '../common/contextkeys.js';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
|
||||
import { IConfigurationService } from '../../platform/configuration/common/configuration.js';
|
||||
@@ -203,6 +203,7 @@ export class WorkbenchContextKeysHandler
|
||||
import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService.js';
|
||||
@@ -202,6 +202,7 @@ export class WorkbenchContextKeysHandler
|
||||
// code-server
|
||||
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
|
||||
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
|
||||
@ -234,7 +234,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||
@@ -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 IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
|
||||
|
||||
@ -48,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
-[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
||||
- try {
|
||||
- if (!fs.existsSync(f)) {
|
||||
- fs.mkdirSync(f, { mode: 0o700 });
|
||||
- fs.mkdirSync(f, { mode: 0o700, recursive: true });
|
||||
- }
|
||||
- } catch (err) { console.error(err); }
|
||||
-});
|
||||
@ -68,7 +68,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
+ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
||||
+ try {
|
||||
+ if (!fs.existsSync(f)) {
|
||||
+ fs.mkdirSync(f, { mode: 0o700 });
|
||||
+ fs.mkdirSync(f, { mode: 0o700, recursive: true });
|
||||
+ }
|
||||
+ } catch (err) { console.error(err); }
|
||||
+ });
|
||||
@ -109,24 +109,6 @@ Index: code-server/lib/vscode/src/vs/base/common/processes.ts
|
||||
];
|
||||
const envKeys = Object.keys(env);
|
||||
envKeys
|
||||
Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
|
||||
@@ -78,8 +78,11 @@ export class BrowserDialogHandler extend
|
||||
|
||||
async about(): Promise<void> {
|
||||
const detailString = (useAgo: boolean): string => {
|
||||
- return localize('aboutDetail',
|
||||
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
+ return localize('aboutCodeServerDetail',
|
||||
+ "code-server: {0}",
|
||||
+ this.productService.codeServerVersion ? `v${this.productService.codeServerVersion}` : 'Unknown'
|
||||
+ ) + '\n' + localize('aboutDetail',
|
||||
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
this.productService.version || 'Unknown',
|
||||
this.productService.commit || 'Unknown',
|
||||
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
|
||||
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
@ -190,7 +172,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
|
||||
import { IProgressService } from '../../platform/progress/common/progress.js';
|
||||
import { DelayedLogChannel } from '../services/output/common/delayedLogChannel.js';
|
||||
import { dirname, joinPath } from '../../base/common/resources.js';
|
||||
@@ -130,6 +131,9 @@ export class BrowserMain extends Disposa
|
||||
@@ -133,6 +134,9 @@ export class BrowserMain extends Disposa
|
||||
// Startup
|
||||
const instantiationService = workbench.startup();
|
||||
|
||||
@ -204,7 +186,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -56,6 +56,8 @@ export type ExtensionVirtualWorkspaceSup
|
||||
@@ -65,6 +65,8 @@ export type ExtensionVirtualWorkspaceSup
|
||||
};
|
||||
|
||||
export interface IProductConfiguration {
|
||||
@ -281,9 +263,9 @@ Index: code-server/lib/vscode/src/server-main.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/server-main.ts
|
||||
+++ code-server/lib/vscode/src/server-main.ts
|
||||
@@ -25,6 +25,9 @@ const __dirname = path.dirname(fileURLTo
|
||||
@@ -22,6 +22,9 @@ import { IServerAPI } from './vs/server/
|
||||
perf.mark('code/server/start');
|
||||
(globalThis as any).vscodeServerStartTime = performance.now();
|
||||
(globalThis as { vscodeServerStartTime?: number }).vscodeServerStartTime = performance.now();
|
||||
|
||||
+// This is not indented to make the diff less noisy. We need to move this out
|
||||
+// of the top-level so it will not run immediately and we can control the start.
|
||||
@ -291,15 +273,15 @@ Index: code-server/lib/vscode/src/server-main.ts
|
||||
// Do a quick parse to determine if a server or the cli needs to be started
|
||||
const parsedArgs = minimist(process.argv.slice(2), {
|
||||
boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'],
|
||||
@@ -153,6 +156,7 @@ if (shouldSpawnCli) {
|
||||
@@ -150,6 +153,7 @@ if (shouldSpawnCli) {
|
||||
}
|
||||
});
|
||||
}
|
||||
+}
|
||||
|
||||
function sanitizeStringArg(val: any): string | undefined {
|
||||
function sanitizeStringArg(val: unknown): string | undefined {
|
||||
if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array
|
||||
@@ -286,3 +290,22 @@ function prompt(question: string): Promi
|
||||
@@ -283,3 +287,22 @@ function prompt(question: string): Promi
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -310,7 +292,7 @@ Index: code-server/lib/vscode/src/server-main.ts
|
||||
+ osLocale: 'en',
|
||||
+ commit: product.commit,
|
||||
+ userDataPath: '',
|
||||
+ nlsMetadataPath: __dirname,
|
||||
+ nlsMetadataPath: import.meta.dirname,
|
||||
+ });
|
||||
+ return loadCode(nlsConfiguration);
|
||||
+}
|
||||
@ -322,3 +304,21 @@ Index: code-server/lib/vscode/src/server-main.ts
|
||||
+if (!process.env.CODE_SERVER_PARENT_PID) {
|
||||
+ start();
|
||||
+}
|
||||
Index: code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/dialogs/browser/dialog.ts
|
||||
@@ -45,8 +45,11 @@ export function createWorkbenchDialogOpt
|
||||
|
||||
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
|
||||
const detailString = (useAgo: boolean): string => {
|
||||
- return localize('aboutDetail',
|
||||
- "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
+ return localize('aboutCodeServerDetail',
|
||||
+ "code-server: {0}",
|
||||
+ productService.codeServerVersion ? `v${productService.codeServerVersion}` : 'Unknown'
|
||||
+ ) + '\n' + localize('aboutDetail',
|
||||
+ "Code: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
productService.version || 'Unknown',
|
||||
productService.commit || 'Unknown',
|
||||
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',
|
||||
|
||||
@ -32,7 +32,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
|
||||
@@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO
|
||||
*/
|
||||
readonly configurationDefaults?: Record<string, any>;
|
||||
readonly configurationDefaults?: Record<string, unknown>;
|
||||
|
||||
+ /**
|
||||
+ * Path to the user data directory.
|
||||
@ -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;
|
||||
this.workspace.update(workspace);
|
||||
} else {
|
||||
|
||||
@ -8,7 +8,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -59,6 +59,7 @@ export interface IProductConfiguration {
|
||||
@@ -68,6 +68,7 @@ export interface IProductConfiguration {
|
||||
readonly codeServerVersion?: string
|
||||
readonly rootEndpoint?: string
|
||||
readonly updateEndpoint?: string
|
||||
@ -20,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -17,6 +17,7 @@ import { join } from '../../base/common/
|
||||
@@ -18,6 +18,7 @@ import { ProtocolConstants } from '../..
|
||||
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check': { type: 'boolean' },
|
||||
@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -101,6 +102,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -105,6 +106,7 @@ export const serverOptions: OptionDescri
|
||||
export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
|
||||
@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
@@ -49,6 +49,16 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
||||
@@ -49,6 +49,17 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
||||
version: pkg.version
|
||||
});
|
||||
}
|
||||
@ -28,6 +28,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
+ extensionsGallery: env.EXTENSIONS_GALLERY ? JSON.parse(env.EXTENSIONS_GALLERY) : (product.extensionsGallery || {
|
||||
+ serviceUrl: "https://open-vsx.org/vscode/gallery",
|
||||
+ itemUrl: "https://open-vsx.org/vscode/item",
|
||||
+ extensionUrlTemplate: "https://open-vsx.org/vscode/gallery/{publisher}/{name}/latest",
|
||||
+ resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
|
||||
+ controlUrl: "",
|
||||
+ recommendationsUrl: "",
|
||||
@ -89,3 +90,18 @@ Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/ext
|
||||
}
|
||||
|
||||
}
|
||||
Index: code-server/lib/vscode/src/vs/platform/externalServices/common/marketplace.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/externalServices/common/marketplace.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/externalServices/common/marketplace.ts
|
||||
@@ -26,6 +26,10 @@ export async function resolveMarketplace
|
||||
'User-Agent': `VSCode ${version} (${productService.nameShort})`
|
||||
};
|
||||
|
||||
+ if (productService.extensionsGallery?.authorizationHeaderToken) {
|
||||
+ headers['Authorization'] = `Bearer ${productService.extensionsGallery.authorizationHeaderToken}`;
|
||||
+ }
|
||||
+
|
||||
if (supportsTelemetry(productService, environmentService) && getTelemetryLevel(configurationService) === TelemetryLevel.USAGE) {
|
||||
const serviceMachineId = await getServiceMachineId(environmentService, fileService, storageService);
|
||||
headers['X-Market-User-Id'] = serviceMachineId;
|
||||
|
||||
@ -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/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 {
|
||||
|
||||
@ -30,7 +30,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -60,6 +60,7 @@ export interface IProductConfiguration {
|
||||
@@ -69,6 +69,7 @@ export interface IProductConfiguration {
|
||||
readonly rootEndpoint?: string
|
||||
readonly updateEndpoint?: string
|
||||
readonly logoutEndpoint?: string
|
||||
@ -83,7 +83,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
|
||||
@@ -291,7 +291,7 @@ export async function createTerminalEnvi
|
||||
@@ -292,7 +292,7 @@ export async function createTerminalEnvi
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
@ -104,7 +104,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
|
||||
import type { IURLCallbackProvider } from '../../../workbench/services/url/browser/urlService.js';
|
||||
import { create } from '../../../workbench/workbench.web.main.internal.js';
|
||||
|
||||
@@ -599,6 +600,39 @@ class WorkspaceProvider implements IWork
|
||||
@@ -606,6 +607,39 @@ class WorkspaceProvider implements IWork
|
||||
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
|
||||
workspaceProvider: WorkspaceProvider.create(config),
|
||||
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
|
||||
|
||||
@ -6,7 +6,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -61,6 +61,10 @@ export interface IProductConfiguration {
|
||||
@@ -70,6 +70,10 @@ export interface IProductConfiguration {
|
||||
readonly updateEndpoint?: string
|
||||
readonly logoutEndpoint?: string
|
||||
readonly proxyEndpointTemplate?: string
|
||||
|
||||
@ -6,21 +6,21 @@ not host our source maps there and want them to be self-hosted even if we could.
|
||||
|
||||
To test try debugging/browsing the source of a build in a browser.
|
||||
|
||||
Index: code-server/lib/vscode/build/gulpfile.reh.js
|
||||
Index: code-server/lib/vscode/build/gulpfile.reh.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/gulpfile.reh.js
|
||||
+++ code-server/lib/vscode/build/gulpfile.reh.js
|
||||
@@ -257,8 +257,7 @@ function packageTask(type, platform, arc
|
||||
|
||||
--- code-server.orig/lib/vscode/build/gulpfile.reh.ts
|
||||
+++ code-server/lib/vscode/build/gulpfile.reh.ts
|
||||
@@ -257,8 +257,7 @@ function packageTask(type: string, platf
|
||||
return () => {
|
||||
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
|
||||
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
|
||||
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + sourceFolderName), 'out'); }))
|
||||
- .pipe(util.setExecutableBit(['**/*.sh']))
|
||||
- .pipe(filter(['**', '!**/*.{js,css}.map']));
|
||||
+ .pipe(util.setExecutableBit(['**/*.sh']));
|
||||
|
||||
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
|
||||
const isUIExtension = (manifest) => {
|
||||
@@ -297,9 +296,9 @@ function packageTask(type, platform, arc
|
||||
const isUIExtension = (manifest: { extensionKind?: string; main?: string; contributes?: Record<string, unknown> }) => {
|
||||
@@ -298,9 +297,9 @@ function packageTask(type: string, platf
|
||||
.map(name => `.build/extensions/${name}/**`);
|
||||
|
||||
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
|
||||
@ -31,8 +31,8 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
|
||||
+ const sources = es.merge(src, extensions, extensionsCommonDependencies);
|
||||
|
||||
let version = packageJson.version;
|
||||
const quality = product.quality;
|
||||
@@ -452,7 +451,7 @@ function tweakProductForServerWeb(produc
|
||||
const quality = (product as typeof product & { quality?: string }).quality;
|
||||
@@ -453,7 +452,7 @@ function tweakProductForServerWeb(produc
|
||||
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
|
||||
bundleTask,
|
||||
util.rimraf(`out-vscode-${type}-min`),
|
||||
|
||||
@ -96,7 +96,7 @@ Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
|
||||
import minimist from 'minimist';
|
||||
import * as nativeWatchdog from 'native-watchdog';
|
||||
import * as net from 'net';
|
||||
@@ -436,7 +437,28 @@ async function startExtensionHostProcess
|
||||
@@ -469,7 +470,28 @@ async function startExtensionHostProcess
|
||||
);
|
||||
|
||||
// rewrite onTerminate-function to be a proper shutdown
|
||||
|
||||
@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
|
||||
import { NullPolicyService } from '../../platform/policy/common/policy.js';
|
||||
import { OneDataSystemAppender } from '../../platform/telemetry/node/1dsAppender.js';
|
||||
import { LoggerService } from '../../platform/log/node/loggerService.js';
|
||||
@@ -163,11 +165,23 @@ export async function setupServerService
|
||||
@@ -166,11 +168,23 @@ export async function setupServerService
|
||||
const requestService = new RequestService('remote', configurationService, environmentService, logService);
|
||||
services.set(IRequestService, requestService);
|
||||
|
||||
@ -147,7 +147,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -65,6 +65,7 @@ export interface IProductConfiguration {
|
||||
@@ -74,6 +74,7 @@ export interface IProductConfiguration {
|
||||
readonly path: string;
|
||||
readonly scope: string;
|
||||
}
|
||||
@ -159,7 +159,7 @@ Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
|
||||
@@ -57,7 +57,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
||||
@@ -58,7 +58,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
|
||||
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
|
||||
controlUrl: "",
|
||||
recommendationsUrl: "",
|
||||
|
||||
@ -4,7 +4,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -22,6 +22,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -23,6 +23,7 @@ export const serverOptions: OptionDescri
|
||||
'disable-file-uploads': { type: 'boolean' },
|
||||
'disable-getting-started-override': { type: 'boolean' },
|
||||
'locale': { type: 'string' },
|
||||
@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -111,6 +112,7 @@ export interface ServerParsedArgs {
|
||||
@@ -115,6 +116,7 @@ export interface ServerParsedArgs {
|
||||
'disable-file-uploads'?: boolean;
|
||||
'disable-getting-started-override'?: boolean,
|
||||
'locale'?: string
|
||||
|
||||
@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
|
||||
+++ code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
@@ -58,6 +58,7 @@ export type ExtensionVirtualWorkspaceSup
|
||||
@@ -67,6 +67,7 @@ export type ExtensionVirtualWorkspaceSup
|
||||
export interface IProductConfiguration {
|
||||
readonly codeServerVersion?: string
|
||||
readonly rootEndpoint?: string
|
||||
@ -101,6 +101,14 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
|
||||
readonly version: string;
|
||||
readonly date?: string;
|
||||
@@ -113,6 +114,7 @@ export interface IProductConfiguration {
|
||||
readonly resourceUrlTemplate: string;
|
||||
readonly nlsBaseUrl: string;
|
||||
readonly accessSKUs?: string[];
|
||||
+ readonly authorizationHeaderToken?: string;
|
||||
};
|
||||
|
||||
readonly mcpGallery?: {
|
||||
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
@ -117,8 +125,8 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
@@ -15,6 +15,8 @@ import { joinPath } from '../../base/com
|
||||
import { join } from '../../base/common/path.js';
|
||||
@@ -16,6 +16,8 @@ import { join } from '../../base/common/
|
||||
import { ProtocolConstants } from '../../base/parts/ipc/common/ipc.net.js';
|
||||
|
||||
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
|
||||
+ /* ----- code-server ----- */
|
||||
@ -126,7 +134,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -97,6 +99,8 @@ export const serverOptions: OptionDescri
|
||||
@@ -101,6 +103,8 @@ export const serverOptions: OptionDescri
|
||||
};
|
||||
|
||||
export interface ServerParsedArgs {
|
||||
|
||||
@ -70,12 +70,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
- content="default-src 'none'; script-src 'sha256-gEAyFzmkyqMoTTnN+3KReFUYoHsK4RAJEb+6eiul+UY=' '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-TaWGDzV7c9rUH2q/5ygOyYUHSyHIqBMYfucPh3lnKvU=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
+ content="default-src 'none'; script-src 'sha256-nQZh+9dHKZP2cHbhYlCbWDtqxxJtGjRGBx57zNP2DZM=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport"
|
||||
@@ -238,7 +238,7 @@
|
||||
@@ -256,7 +256,7 @@
|
||||
}
|
||||
|
||||
const swPath = encodeURI(`service-worker.js?v=${expectedWorkerVersion}&vscode-resource-base-authority=${searchParams.get('vscode-resource-base-authority')}&remoteAuthority=${searchParams.get('remoteAuthority') ?? ''}`);
|
||||
@ -84,7 +84,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
|
||||
.then(async registration => {
|
||||
/**
|
||||
* @param {MessageEvent} event
|
||||
@@ -351,6 +351,12 @@
|
||||
@@ -370,6 +370,12 @@
|
||||
|
||||
const hostname = location.hostname;
|
||||
|
||||
|
||||
@ -15,7 +15,8 @@ body {
|
||||
color: #111;
|
||||
color: light-dark(#111, #ddd);
|
||||
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";
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -24,6 +24,6 @@ export class HttpError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export enum CookieKeys {
|
||||
Session = "code-server-session",
|
||||
export function getCookieSessionName(suffix?: string): string {
|
||||
return suffix ? `code-server-session-${suffix.replace(/[^a-zA-Z0-9-]/g, "-")}` : "code-server-session"
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ export interface UserProvidedCodeArgs {
|
||||
"disable-getting-started-override"?: boolean
|
||||
"disable-proxy"?: boolean
|
||||
"session-socket"?: string
|
||||
"cookie-suffix"?: string
|
||||
"link-protection-trusted-domains"?: string[]
|
||||
// locale is used by both VS Code and code-server.
|
||||
locale?: string
|
||||
@ -94,6 +95,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
|
||||
"welcome-text"?: string
|
||||
"abs-proxy-base-path"?: string
|
||||
i18n?: string
|
||||
"idle-timeout-seconds"?: number
|
||||
/* Positional arguments. */
|
||||
_?: string[]
|
||||
}
|
||||
@ -171,6 +173,12 @@ export const options: Options<Required<UserProvidedArgs>> = {
|
||||
"session-socket": {
|
||||
type: "string",
|
||||
},
|
||||
"cookie-suffix": {
|
||||
type: "string",
|
||||
description:
|
||||
"Adds a suffix to the cookie. This can prevent a collision of cookies for subdomains, making them explixit. \n" +
|
||||
"Without this flag, no suffix is used. This can also be set with CODE_SERVER_COOKIE_SUFFIX set to any string.",
|
||||
},
|
||||
"disable-file-downloads": {
|
||||
type: "boolean",
|
||||
description:
|
||||
@ -303,6 +311,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
|
||||
path: true,
|
||||
description: "Path to JSON file with custom translations. Merges with default strings and supports all i18n keys.",
|
||||
},
|
||||
"idle-timeout-seconds": {
|
||||
type: "number",
|
||||
description: "Timeout in seconds to wait before shutting down when idle.",
|
||||
},
|
||||
}
|
||||
|
||||
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
|
||||
@ -396,6 +408,10 @@ export const parse = (
|
||||
throw new Error("--github-auth can only be set in the config file or passed in via $GITHUB_TOKEN")
|
||||
}
|
||||
|
||||
if (key === "idle-timeout-seconds" && Number(value) <= 60) {
|
||||
throw new Error("--idle-timeout-seconds must be greater than 60 seconds.")
|
||||
}
|
||||
|
||||
const option = options[key]
|
||||
if (option.type === "boolean") {
|
||||
;(args[key] as boolean) = true
|
||||
@ -607,10 +623,24 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
||||
usingEnvPassword = false
|
||||
}
|
||||
|
||||
if (process.env.CODE_SERVER_COOKIE_SUFFIX) {
|
||||
args["cookie-suffix"] = process.env.CODE_SERVER_COOKIE_SUFFIX
|
||||
}
|
||||
|
||||
if (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.
|
||||
delete process.env.PASSWORD
|
||||
delete process.env.HASHED_PASSWORD
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import { promises as fs } from "fs"
|
||||
import { Emitter } from "../common/emitter"
|
||||
|
||||
/**
|
||||
* Provides a heartbeat using a local file to indicate activity.
|
||||
@ -8,6 +9,9 @@ export class Heart {
|
||||
private heartbeatTimer?: NodeJS.Timeout
|
||||
private heartbeatInterval = 60000
|
||||
public lastHeartbeat = 0
|
||||
private readonly _onChange = new Emitter<"alive" | "expired" | "unknown">()
|
||||
readonly onChange = this._onChange.event
|
||||
private state: "alive" | "expired" | "unknown" = "expired"
|
||||
|
||||
public constructor(
|
||||
private readonly heartbeatPath: string,
|
||||
@ -17,6 +21,13 @@ export class Heart {
|
||||
this.alive = this.alive.bind(this)
|
||||
}
|
||||
|
||||
private setState(state: typeof this.state) {
|
||||
if (this.state !== state) {
|
||||
this.state = state
|
||||
this._onChange.emit(this.state)
|
||||
}
|
||||
}
|
||||
|
||||
public alive(): boolean {
|
||||
const now = Date.now()
|
||||
return now - this.lastHeartbeat < this.heartbeatInterval
|
||||
@ -28,6 +39,7 @@ export class Heart {
|
||||
*/
|
||||
public async beat(): Promise<void> {
|
||||
if (this.alive()) {
|
||||
this.setState("alive")
|
||||
return
|
||||
}
|
||||
|
||||
@ -36,7 +48,22 @@ export class Heart {
|
||||
if (typeof this.heartbeatTimer !== "undefined") {
|
||||
clearTimeout(this.heartbeatTimer)
|
||||
}
|
||||
this.heartbeatTimer = setTimeout(() => heartbeatTimer(this.isActive, this.beat), this.heartbeatInterval)
|
||||
|
||||
this.heartbeatTimer = setTimeout(async () => {
|
||||
try {
|
||||
if (await this.isActive()) {
|
||||
this.beat()
|
||||
} else {
|
||||
this.setState("expired")
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
logger.warn((error as Error).message)
|
||||
this.setState("unknown")
|
||||
}
|
||||
}, this.heartbeatInterval)
|
||||
|
||||
this.setState("alive")
|
||||
|
||||
try {
|
||||
return await fs.writeFile(this.heartbeatPath, "")
|
||||
} catch (error: any) {
|
||||
@ -53,20 +80,3 @@ export class Heart {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for the heartbeatTimer.
|
||||
*
|
||||
* If heartbeat is active, call beat. Otherwise do nothing.
|
||||
*
|
||||
* Extracted to make it easier to test.
|
||||
*/
|
||||
export async function heartbeatTimer(isActive: Heart["isActive"], beat: Heart["beat"]) {
|
||||
try {
|
||||
if (await isActive()) {
|
||||
beat()
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
logger.warn((error as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { field, logger } from "@coder/logger"
|
||||
import * as express from "express"
|
||||
import * as expressCore from "express-serve-static-core"
|
||||
import * as http from "http"
|
||||
import * as net from "net"
|
||||
import * as qs from "qs"
|
||||
import qs from "qs"
|
||||
import { Disposable } from "../common/emitter"
|
||||
import { CookieKeys, HttpCode, HttpError } from "../common/http"
|
||||
import { HttpCode, HttpError } from "../common/http"
|
||||
import { normalize } from "../common/util"
|
||||
import { AuthType, DefaultedArgs } from "./cli"
|
||||
import { version as codeServerVersion } from "./constants"
|
||||
@ -41,6 +40,7 @@ declare global {
|
||||
heart: Heart
|
||||
settings: SettingsProvider<CoderSettings>
|
||||
updater: UpdateProvider
|
||||
cookieSessionName: string
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ export const authenticated = async (req: express.Request): Promise<boolean> => {
|
||||
const passwordMethod = getPasswordMethod(hashedPasswordFromArgs)
|
||||
const isCookieValidArgs: IsCookieValidArgs = {
|
||||
passwordMethod,
|
||||
cookieKey: sanitizeString(req.cookies[CookieKeys.Session]),
|
||||
cookieKey: sanitizeString(req.cookies[req.cookieSessionName]),
|
||||
passwordFromArgs: req.args.password || "",
|
||||
hashedPasswordFromArgs: req.args["hashed-password"],
|
||||
}
|
||||
@ -185,12 +185,7 @@ export const constructRedirectPath = (req: express.Request, query: qs.ParsedQs,
|
||||
* preserved. `to` should be a simple path without any query parameters
|
||||
* `override` will merge with the existing query (use `undefined` to unset).
|
||||
*/
|
||||
export const redirect = (
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
to: string,
|
||||
override: expressCore.Query = {},
|
||||
): void => {
|
||||
export const redirect = (req: express.Request, res: express.Response, to: string, override: qs.ParsedQs = {}): void => {
|
||||
const query = Object.assign({}, req.query, override)
|
||||
Object.keys(override).forEach((key) => {
|
||||
if (typeof override[key] === "undefined") {
|
||||
|
||||
@ -11,6 +11,7 @@ import { loadCustomStrings } from "./i18n"
|
||||
import { register } from "./routes"
|
||||
import { VSCodeModule } from "./routes/vscode"
|
||||
import { isDirectory, open } from "./util"
|
||||
import { wrapper } from "./wrapper"
|
||||
|
||||
/**
|
||||
* Return true if the user passed an extension-related VS Code flag.
|
||||
@ -141,7 +142,7 @@ export const runCodeServer = async (
|
||||
const app = await createApp(args)
|
||||
const protocol = args.cert ? "https" : "http"
|
||||
const serverAddress = ensureAddress(app.server, protocol)
|
||||
const disposeRoutes = await register(app, args)
|
||||
const { disposeRoutes, heart } = await register(app, args)
|
||||
|
||||
logger.info(`Using config file ${args.config}`)
|
||||
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
|
||||
@ -166,6 +167,27 @@ export const runCodeServer = async (
|
||||
logger.info(" - Not serving HTTPS")
|
||||
}
|
||||
|
||||
if (args["idle-timeout-seconds"]) {
|
||||
logger.info(` - Idle timeout set to ${args["idle-timeout-seconds"]} seconds`)
|
||||
|
||||
let idleShutdownTimer: NodeJS.Timeout | undefined
|
||||
const startIdleShutdownTimer = () => {
|
||||
idleShutdownTimer = setTimeout(() => {
|
||||
logger.warn(`Idle timeout of ${args["idle-timeout-seconds"]} seconds exceeded`)
|
||||
wrapper.exit(0)
|
||||
}, args["idle-timeout-seconds"]! * 1000)
|
||||
}
|
||||
|
||||
startIdleShutdownTimer()
|
||||
|
||||
heart.onChange((state) => {
|
||||
clearTimeout(idleShutdownTimer)
|
||||
if (state === "expired") {
|
||||
startIdleShutdownTimer()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (args["disable-proxy"]) {
|
||||
logger.info(" - Proxy disabled")
|
||||
} else if (args["proxy-domain"].length > 0) {
|
||||
|
||||
@ -28,6 +28,12 @@ export const errorHasCode = (error: any): error is ErrorWithCode => {
|
||||
|
||||
const notFoundCodes = [404, "ENOENT", "EISDIR"]
|
||||
|
||||
/**
|
||||
* Final HTTP error handler.
|
||||
*
|
||||
* Note: This handler intentionally does not call `next()` even though it
|
||||
* accepts it as an argument; it is expected to be mounted last.
|
||||
*/
|
||||
export const errorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
|
||||
let statusCode = 500
|
||||
|
||||
@ -61,6 +67,12 @@ export const errorHandler: express.ErrorRequestHandler = async (err, req, res, n
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Final WebSocket error handler.
|
||||
*
|
||||
* Note: This handler intentionally does not call `next()` even though it
|
||||
* accepts it as an argument; it is expected to be mounted last.
|
||||
*/
|
||||
export const wsErrorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
|
||||
let statusCode = 500
|
||||
if (errorHasStatusCode(err)) {
|
||||
|
||||
@ -5,7 +5,7 @@ import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import * as tls from "tls"
|
||||
import { Disposable } from "../../common/emitter"
|
||||
import { HttpCode, HttpError } from "../../common/http"
|
||||
import { getCookieSessionName, HttpCode, HttpError } from "../../common/http"
|
||||
import { plural } from "../../common/util"
|
||||
import { App } from "../app"
|
||||
import { AuthType, DefaultedArgs } from "../cli"
|
||||
@ -28,7 +28,10 @@ import * as vscode from "./vscode"
|
||||
/**
|
||||
* Register all routes and middleware.
|
||||
*/
|
||||
export const register = async (app: App, args: DefaultedArgs): Promise<Disposable["dispose"]> => {
|
||||
export const register = async (
|
||||
app: App,
|
||||
args: DefaultedArgs,
|
||||
): Promise<{ disposeRoutes: Disposable["dispose"]; heart: Heart }> => {
|
||||
const heart = new Heart(path.join(paths.data, "heartbeat"), async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// getConnections appears to not call the callback when there are no more
|
||||
@ -58,6 +61,8 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
const settings = new SettingsProvider<CoderSettings>(path.join(args["user-data-dir"], "coder.json"))
|
||||
const updater = new UpdateProvider("https://api.github.com/repos/coder/code-server/releases/latest", settings)
|
||||
|
||||
const cookieSessionName = getCookieSessionName(args["cookie-suffix"])
|
||||
|
||||
const common: express.RequestHandler = (req, _, next) => {
|
||||
// /healthz|/healthz/ needs to be excluded otherwise health checks will make
|
||||
// it look like code-server is always in use.
|
||||
@ -72,6 +77,7 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
req.heart = heart
|
||||
req.settings = settings
|
||||
req.updater = updater
|
||||
req.cookieSessionName = cookieSessionName
|
||||
|
||||
next()
|
||||
}
|
||||
@ -173,8 +179,11 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
app.router.use(errorHandler)
|
||||
app.wsRouter.use(wsErrorHandler)
|
||||
|
||||
return () => {
|
||||
heart.dispose()
|
||||
vscode.dispose()
|
||||
return {
|
||||
disposeRoutes: () => {
|
||||
heart.dispose()
|
||||
vscode.dispose()
|
||||
},
|
||||
heart,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ import { Router, Request } from "express"
|
||||
import { promises as fs } from "fs"
|
||||
import { RateLimiter as Limiter } from "limiter"
|
||||
import * as path from "path"
|
||||
import { CookieKeys } from "../../common/http"
|
||||
import { rootPath } from "../constants"
|
||||
import { authenticated, getCookieOptions, redirect, replaceTemplates } from "../http"
|
||||
import i18n from "../i18n"
|
||||
@ -95,7 +94,7 @@ router.post<{}, string, { password?: string; base?: string } | undefined, { to?:
|
||||
if (isPasswordValid) {
|
||||
// The hash does not add any actual security but we do it for
|
||||
// obfuscation purposes (and as a side effect it handles escaping).
|
||||
res.cookie(CookieKeys.Session, hashedPassword, getCookieOptions(req))
|
||||
res.cookie(req.cookieSessionName, hashedPassword, getCookieOptions(req))
|
||||
|
||||
const to = (typeof req.query.to === "string" && req.query.to) || "/"
|
||||
return redirect(req, res, to, { to: undefined })
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Router } from "express"
|
||||
import { CookieKeys } from "../../common/http"
|
||||
import { getCookieOptions, redirect } from "../http"
|
||||
import { sanitizeString } from "../util"
|
||||
|
||||
@ -7,7 +6,7 @@ export const router = Router()
|
||||
|
||||
router.get<{}, undefined, undefined, { base?: string; to?: string }>("/", async (req, res) => {
|
||||
// Must use the *identical* properties used to set the cookie.
|
||||
res.clearCookie(CookieKeys.Session, getCookieOptions(req))
|
||||
res.clearCookie(req.cookieSessionName, getCookieOptions(req))
|
||||
|
||||
const to = sanitizeString(req.query.to) || "/"
|
||||
return redirect(req, res, to, { to: undefined, base: undefined, href: undefined })
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import { Query } from "express-serve-static-core"
|
||||
import type { ParsedQs } from "qs"
|
||||
import { promises as fs } from "fs"
|
||||
|
||||
export type Settings = { [key: string]: Settings | string | boolean | number }
|
||||
@ -52,5 +52,5 @@ export interface UpdateSettings {
|
||||
* Global code-server settings.
|
||||
*/
|
||||
export interface CoderSettings extends UpdateSettings {
|
||||
query?: Query
|
||||
query?: ParsedQs
|
||||
}
|
||||
|
||||
@ -2,8 +2,9 @@ import { logger } from "@coder/logger"
|
||||
import express from "express"
|
||||
import * as http from "http"
|
||||
import * as path from "path"
|
||||
import { HttpCode } from "../common/http"
|
||||
import { HttpCode, HttpError } from "../common/http"
|
||||
import { listen } from "./app"
|
||||
import { errorHandler } from "./routes/errors"
|
||||
import { canConnect } from "./util"
|
||||
|
||||
export interface EditorSessionEntry {
|
||||
@ -44,24 +45,18 @@ export async function makeEditorSessionManagerServer(
|
||||
async (req, res) => {
|
||||
const filePath = req.query.filePath
|
||||
if (!filePath) {
|
||||
res.status(HttpCode.BadRequest).send("filePath is required")
|
||||
return
|
||||
}
|
||||
try {
|
||||
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
|
||||
const response: GetSessionResponse = { socketPath }
|
||||
res.json(response)
|
||||
} catch (error: unknown) {
|
||||
res.status(HttpCode.ServerError).send(error)
|
||||
throw new HttpError("filePath is required", HttpCode.BadRequest)
|
||||
}
|
||||
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
|
||||
const response: GetSessionResponse = { socketPath }
|
||||
res.json(response)
|
||||
},
|
||||
)
|
||||
|
||||
router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => {
|
||||
const entry = req.body?.entry
|
||||
if (!entry) {
|
||||
res.status(400).send("entry is required")
|
||||
return
|
||||
throw new HttpError("entry is required", HttpCode.BadRequest)
|
||||
}
|
||||
editorSessionManager.addSession(entry)
|
||||
res.status(200).send("session added")
|
||||
@ -70,13 +65,14 @@ export async function makeEditorSessionManagerServer(
|
||||
router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => {
|
||||
const socketPath = req.body?.socketPath
|
||||
if (!socketPath) {
|
||||
res.status(400).send("socketPath is required")
|
||||
return
|
||||
throw new HttpError("socketPath is required", HttpCode.BadRequest)
|
||||
}
|
||||
editorSessionManager.deleteSession(socketPath)
|
||||
res.status(200).send("session deleted")
|
||||
})
|
||||
|
||||
router.use(errorHandler)
|
||||
|
||||
const server = http.createServer(router)
|
||||
try {
|
||||
await listen(server, { socket: codeServerSocketPath })
|
||||
|
||||
910
test/package-lock.json
generated
910
test/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -3,26 +3,23 @@
|
||||
"#": "We must put jest in a sub-directory otherwise VS Code somehow picks up the types and generates conflicts with mocha.",
|
||||
"devDependencies": {
|
||||
"@jest-mock/express": "^1.4.5",
|
||||
"@playwright/test": "^1.46.0",
|
||||
"@playwright/test": "^1.56.1",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/jsdom": "^16.2.13",
|
||||
"@types/node-fetch": "^2.5.8",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"@types/wtfnode": "^0.7.0",
|
||||
"argon2": "^0.28.0",
|
||||
"argon2": "^0.44.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"jest": "^27.3.1",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"jsdom": "^16.4.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"playwright": "^1.46.0",
|
||||
"supertest": "^6.1.6",
|
||||
"playwright": "^1.56.1",
|
||||
"ts-jest": "^27.0.7",
|
||||
"wtfnode": "^0.9.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"argon2/@mapbox/node-pre-gyp/tar": "^6.1.9",
|
||||
"set-value": "^4.0.1",
|
||||
"tmpl": "^1.0.5",
|
||||
"path-parse": "^1.0.7",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import { readFile, writeFile, stat, utimes } from "fs/promises"
|
||||
import { Heart, heartbeatTimer } from "../../../src/node/heart"
|
||||
import { Heart } from "../../../src/node/heart"
|
||||
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
|
||||
|
||||
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
|
||||
@ -82,7 +82,52 @@ describe("Heart", () => {
|
||||
})
|
||||
|
||||
describe("heartbeatTimer", () => {
|
||||
beforeAll(() => {
|
||||
const testName = "heartbeatTimer"
|
||||
let testDir = ""
|
||||
beforeAll(async () => {
|
||||
await clean(testName)
|
||||
testDir = await tmpdir(testName)
|
||||
mockLogger()
|
||||
})
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers()
|
||||
})
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks()
|
||||
jest.clearAllTimers()
|
||||
jest.useRealTimers()
|
||||
})
|
||||
it("should call isActive when timeout expires", async () => {
|
||||
const isActive = true
|
||||
const mockIsActive = jest.fn().mockResolvedValue(isActive)
|
||||
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
|
||||
await heart.beat()
|
||||
jest.advanceTimersByTime(60 * 1000)
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
})
|
||||
it("should log a warning when isActive rejects", async () => {
|
||||
const errorMsg = "oh no"
|
||||
const error = new Error(errorMsg)
|
||||
const mockIsActive = jest.fn().mockRejectedValue(error)
|
||||
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
|
||||
await heart.beat()
|
||||
jest.advanceTimersByTime(60 * 1000)
|
||||
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
|
||||
})
|
||||
})
|
||||
|
||||
describe("stateChange", () => {
|
||||
const testName = "stateChange"
|
||||
let testDir = ""
|
||||
let heart: Heart
|
||||
beforeAll(async () => {
|
||||
await clean(testName)
|
||||
testDir = await tmpdir(testName)
|
||||
mockLogger()
|
||||
})
|
||||
afterAll(() => {
|
||||
@ -90,23 +135,28 @@ describe("heartbeatTimer", () => {
|
||||
})
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks()
|
||||
if (heart) {
|
||||
heart.dispose()
|
||||
}
|
||||
})
|
||||
it("should call beat when isActive resolves to true", async () => {
|
||||
const isActive = true
|
||||
const mockIsActive = jest.fn().mockResolvedValue(isActive)
|
||||
const mockBeatFn = jest.fn()
|
||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
expect(mockBeatFn).toHaveBeenCalled()
|
||||
it("should change to alive after a beat", async () => {
|
||||
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
|
||||
const mockOnChange = jest.fn()
|
||||
heart.onChange(mockOnChange)
|
||||
await heart.beat()
|
||||
|
||||
expect(mockOnChange.mock.calls[0][0]).toBe("alive")
|
||||
})
|
||||
it("should log a warning when isActive rejects", async () => {
|
||||
const errorMsg = "oh no"
|
||||
const error = new Error(errorMsg)
|
||||
const mockIsActive = jest.fn().mockRejectedValue(error)
|
||||
const mockBeatFn = jest.fn()
|
||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
expect(mockBeatFn).not.toHaveBeenCalled()
|
||||
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
|
||||
it.only("should change to expired when not active", async () => {
|
||||
jest.useFakeTimers()
|
||||
heart = new Heart(`${testDir}/shutdown.txt`, () => new Promise((resolve) => resolve(false)))
|
||||
const mockOnChange = jest.fn()
|
||||
heart.onChange(mockOnChange)
|
||||
await heart.beat()
|
||||
|
||||
await jest.advanceTimersByTime(60 * 1000)
|
||||
expect(mockOnChange.mock.calls[1][0]).toBe("expired")
|
||||
jest.clearAllTimers()
|
||||
jest.useRealTimers()
|
||||
})
|
||||
})
|
||||
|
||||
@ -16,6 +16,7 @@ jest.mock("@coder/logger", () => ({
|
||||
debug: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
named: jest.fn(),
|
||||
level: 0,
|
||||
},
|
||||
field: jest.fn(),
|
||||
@ -94,7 +95,7 @@ describe("main", () => {
|
||||
|
||||
// Mock routes module
|
||||
jest.doMock("../../../src/node/routes", () => ({
|
||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
||||
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
|
||||
}))
|
||||
|
||||
// Mock loadCustomStrings to succeed
|
||||
@ -131,7 +132,7 @@ describe("main", () => {
|
||||
|
||||
// Mock routes module
|
||||
jest.doMock("../../../src/node/routes", () => ({
|
||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
||||
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
|
||||
}))
|
||||
|
||||
// Import runCodeServer after mocking
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user