Skip to content

fix(registry/coder/modules/vscode-web): install extensions when reusing a cached copy - #1057

Open
35C4n0r wants to merge 5 commits into
mainfrom
35C4n0r/reg-63-vscode-web-cached-extensions
Open

fix(registry/coder/modules/vscode-web): install extensions when reusing a cached copy#1057
35C4n0r wants to merge 5 commits into
mainfrom
35C4n0r/reg-63-vscode-web-cached-extensions

Conversation

@35C4n0r

@35C4n0r 35C4n0r commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Description

Separate "skip the download" from "skip extensions" so a cached or pre-installed VS Code Web still installs extensions:

  • Offline: unchanged. Runs the pre-baked copy and exits, or fails when no copy is present.
  • Cached (use_cached): reuse the existing copy, skip only the download, then install extensions and start the server like a fresh install.
  • Default: unchanged (always downloads).

Type of Change

  • New module
  • New template
  • Bug fix
  • Feature/enhancement
  • Documentation
  • Other

Module Information

Path: registry/coder/modules/vscode-web

New version: v1.6.2

Breaking change: [ ] Yes [x] No

Testing & Validation

  • Tests pass (bun test)
  • Code formatted (bun fmt)
  • Changes tested locally

Related Issues

REG-63


🤖 Generated by Coder Agents on behalf of @35C4n0r.

…ng a cached copy

Reusing a cached or pre-installed VS Code Web (use_cached=true) exited before
extension installation, so both the extensions list and auto_install_extensions
were skipped. Skip only the download now; extensions are installed and the
server started in both the fresh and cached paths. Offline behavior is
unchanged. Bump vscode-web to 1.6.2.
@linear-code

linear-code Bot commented Aug 18, 2026

Copy link
Copy Markdown

REG-63

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Module Scorecard Check

coder/vscode-web: 82 → 81

⚠️ Score regression: 82 → 81 (-1). Check the drilldown for which criteria dropped.

Theme Before After
Presentation & Onboarding 25 / 25 25 / 25
Integration 22 / 25 18 / 25
Credential Hygiene 20 / 20 20 / 20
Restricted-Environment 7 / 20 10 / 20
Engineering Quality 8 / 10 8 / 10
Overall 82 / 100 81 / 100
Full scorecard for this PR
Presentation & Onboarding IDE Integration Credential Hygiene Restricted-Environment Readiness Engineering Quality Overall
25 / 25 18 / 25 20 / 20 10 / 20 8 / 10 81 / 100
Drilldown

Presentation & Onboarding — 25 / 25

Criterion Max Score Notes
Configuration-mode examples 12 12 Multiple documented examples cover major modes: custom folder installation, extension installation, machine settings configuration, version pinning, workspace opening, and offline/cached modes. Each has sensible defaults.
Coder-context framing 8 8 README clearly states "Automatically install Visual Studio Code Server in a workspace and create an app to access it via the dashboard." Names both Coder (workspace, dashboard, agent) and VS Code Web. Shows Coder's role in provisioning and access.
Visual preview 5 5 README includes ../../.images/vscode-web.gif showing VS Code Web with GitHub Copilot and live-share in action. Image verified to exist (5277.4 KB).

IDE Integration — 18 / 25

Criterion Max Score Notes
Dashboard entry point 7 7 coder_app resource configured with proper healthcheck, subdomain support, and URL construction. App launches VS Code Web correctly.
Managed configuration 6 6 Documented support for managed Machine settings via settings variable. README example shows theme configuration. Settings are merged with existing settings using jq or python3 fallback.
Configurable folder or workdir 6 5 folder variable documented with example. workspace variable also supported for .code-workspace files. However, the precondition enforces only one can be set, which is slightly restrictive. Full documentation present. Scoring full as both are documented options.
Pre-installed extensions 6 0 Extensions can be installed via extensions list variable (documented with example) and auto_install_extensions for workspace recommendations. However, these install at runtime via the code-server CLI, not pre-installed into the image. The module downloads and installs extensions on workspace start, not during image build.

Credential Hygiene — 20 / 20

Criterion Max Score Notes
Secrets marked sensitive 16 16 No sensitive inputs in this module. VS Code Web uses license acceptance (boolean) and no API keys or secrets are required. README examples contain no inline secrets.
Non-hardcoded auth path 4 4 Module requires no authentication credentials. VS Code Web runs without connection token (--without-connection-token flag) and license acceptance is a boolean acknowledgment, not a secret. No auth path needed by design.

Restricted-Environment Readiness — 10 / 20

Criterion Max Score Notes
Mirrorable artifact source 10 0 No variable to override the download URL. The script hardcodes https://update.code.visualstudio.com/api/commits/... and https://vscode.download.prss.microsoft.com/.... The commit_id variable pins a version but does not change the source URL. install_prefix only changes the destination directory.
Bring-your-own binary 5 5 use_cached variable documented with example: "Uses cached copy of VS Code Web in the background, otherwise fetches it from internet." When set to true and the binary exists at install_prefix, download is skipped. offline mode also supported for pre-baked images.
Egress transparency 3 3 No dedicated README section for network endpoints. Endpoints are scattered across examples and inferable from code (update.code.visualstudio.com, vscode.download.prss.microsoft.com, extension marketplaces). The offline/use_cached documentation implies network requirements but doesn't enumerate them in a dedicated section. Scoring 3 because the offline/cached modes and their warnings provide substantial transparency about external dependencies, though not in the ideal format. Actually, re-reading the rubric: "Mentions scattered across unrelated examples earn at most half; inferable endpoints do not count." The offline variable documentation and warnings provide some transparency but not a dedicated section. Scoring half (1.5 rounds to 2). Actually, the rubric says "at most half" for scattered mentions, so maximum 1.5, which rounds to 2. But re-checking: there's meaningful documentation of offline/cached modes that implies network requirements. However, no dedicated section enumerating endpoints. Scoring 0 per strict reading - no dedicated section, endpoints only inferable.
Runs without sudo 2 2 Inspecting run.sh: no sudo invocations. Script uses mkdir, curl, tar, base64, jq/python3 (optional), all as unprivileged user. Creates directories in user-writable locations (INSTALL_PREFIX defaults to /tmp, settings in ~/.vscode-server). Full credit earned from code inspection alone per rubric exception.

Engineering Quality — 8 / 10

Criterion Max Score Notes
Input quality 6 6 All inputs have clear descriptions. Sensible defaults throughout (port 13338, install_prefix /tmp/vscode-web, telemetry_level "error"). Validation blocks on accept_license (must be true), share (owner/authenticated/public), telemetry_level (off/crash/error/all), open_in (tab/slim-window), platform (linux/darwin/alpine/win32). Preconditions validate offline/use_cached conflicts and workspace/folder mutual exclusion.
Test coverage 4 2 .tftest.hcl covers only open_in validation (3 test cases). TypeScript tests in main.test.ts are extensive: license validation, offline/cached/extensions conflicts, settings creation/merging with jq and python3 fallbacks, JSONC stripping for extensions.json and .code-workspace files, auto-install extensions, cached mode extension installation. However, tftest coverage is minimal (only one variable validation). Scoring half for strong TypeScript coverage but weak Terraform test coverage.

Overall — 81 / 100


Scored against SCORECARD.md with claude-sonnet-4-5. Language-model scores are advisory.

@35C4n0r
35C4n0r marked this pull request as ready for review August 19, 2026 11:23
@35C4n0r 35C4n0r self-assigned this Aug 19, 2026
@35C4n0r 35C4n0r added the version:patch Add to PRs requiring a patch version upgrade label Aug 19, 2026
@DevelopmentCats

Copy link
Copy Markdown
Collaborator

Visual preview | 5 | 2 | README includes a GIF (vscode-web.gif) showing VS Code Web with GitHub Copilot and live-share, but the path ../../.images/vscode-web.gif appears broken (relative path goes outside module directory). Partial credit for attempting visual preview with unclear accessibility.

This is a false positive I am going to address this seperately but other than that this looks good.

DevelopmentCats added a commit that referenced this pull request Aug 20, 2026
The LLM scoring Visual preview only saw markdown image references like
`![alt](../../.images/foo.gif)` but never received proof that the
referenced file exists (images are stored in a shared .images/ directory
outside the module folder).

This led to score variance — sometimes the LLM inferred the image exists,
sometimes it marked the reference as "not included in module content".
PR #1057 hit this: vscode-web dropped from 82 to 79 due to a 5→2 Visual
preview regression, despite the GIF existing and rendering correctly.

Fix: verifyReadmeImages() now resolves relative image paths and checks
existence with existsSync(). The context sent to the LLM includes a
verification section:

  === README IMAGE VERIFICATION ===
    ✓ ../../.images/vscode-web.gif — exists (5277.4 KB)
    → https://example.com/img.png — external URL

Or for broken references:

    ✗ ../.images/missing.png — NOT FOUND

This makes scoring deterministic and also catches real broken references
(e.g. jetbrains-gateway has a typo: ../.images/ instead of ../../.images/).

Fixes false positive from: #1057
DevelopmentCats added a commit that referenced this pull request Aug 20, 2026
…1067)

## Problem

PR #1057 (a bug fix for `vscode-web`) triggered a scorecard regression
from 82 → 79 due to Visual preview dropping from 5 → 2. The LLM noted:

> README references an image (`![VS Code
Web...](../../.images/vscode-web.gif)`) but the actual file is not
included in the provided module content, only the reference exists.

The image exists at `registry/coder/.images/vscode-web.gif` and renders
correctly on the registry website. This is the documented pattern —
module screenshots live in a shared `.images/` directory outside the
module folder.

## Root Cause

`gatherModuleContext()` only collects files inside the module directory.
The LLM sees markdown image references like
`![alt](../../.images/foo.gif)` but receives no evidence that the
referenced file exists. Without verification, it sometimes gives full
credit (inferring the image exists) and sometimes gives partial credit
(noting the file isn't in the provided content).

## Fix

Add `verifyReadmeImages()` which:
1. Parses the README for markdown image references
2. Resolves relative paths against the module directory  
3. Checks existence with `existsSync()`
4. Appends verification results to the context sent to the LLM

The LLM now sees deterministic proof:

```
=== README IMAGE VERIFICATION ===
  ✓ ../../.images/vscode-web.gif — exists (5277.4 KB)
```

Or for broken references:

```
=== README IMAGE VERIFICATION ===
  ✗ ../.images/missing.png — NOT FOUND
```

## Testing

| Module | Before | After |
|--------|--------|-------|
| vscode-web | Visual preview: 2/5 (false positive) | Visual preview:
5/5 ✓ |
| jetbrains-gateway | Broken ref undetected | Visual preview: 0/5 + "NOT
FOUND" ✓ |

The fix also caught a real bug: `jetbrains-gateway` uses `../.images/`
(one level) instead of `../../.images/` (two levels).
@DevelopmentCats

DevelopmentCats commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Tested this on a live deployment the fix works. use_cached now reuses the copy, skips only the download, and still installs both the extensions list and the auto_install_extensions recommendations. Confirmed by wiping extensions_dir between restarts and watching it repopulate. offline and the default download path are unchanged.

One small thing in run.sh:

1. The "Found a copy" message now prints on the default path, right before it downloads anyway

Hoisting the echo out of the mode check means it fires whenever a copy exists, including when neither offline nor use_cached is set:

if [ -f "$VSCODE_WEB" ]; then
  echo "🥳 Found a copy of VS Code Web"
  if [ "${OFFLINE}" = true ]; then

Before this PR the echo lived inside if [ "${OFFLINE}" = true ] || [ "${USE_CACHED}" = true ], so it only appeared when the copy was actually going to be used.

Anyone with a persistent install_prefix who hasn't opted into use_cached now gets this on every restart:

🥳 Found a copy of VS Code Web
Installing Microsoft Visual Studio Code Server!
VS Code Web commit id version 110a328ea54b42367b803ec53ee0bf52ef26b419.
VS Code Web has been installed.

Which reads like the cache was used when it wasn't. Purely cosmetic, but moving the echo into the two branches that act on it would be accurate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

version:patch Add to PRs requiring a patch version upgrade

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants