Use when pulling changes from rstudio/vscode-server into Positron — fetching upstream, triaging commits, and applying diffs
70
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Ports changes from rstudio/vscode-server into Positron as a single "upstream merge from vscode-server" commit. A full git merge is not possible — the two repos are parallel VSCode forks with no shared git ancestry — so changes are applied manually and bundled into one commit.
Use this skill when:
rstudio/vscode-server into PositronThe upstream remote must be configured:
git remote -v # should show: upstream → git@github.com:rstudio/vscode-server.git (push disabled)Use the helper script to fetch upstream and list candidates in one shot:
.claude/skills/positron-pull-vscode-server/scripts/enumerate-upstream.sh <baseline-sha>Find <baseline-sha> — it's the upstream/main HEAD recorded after the previous run. After each run, note it for next time:
git rev-parse upstream/mainIf starting fresh with no recorded SHA, look at the Brings in: lines of the last upstream merge commit, find the earliest of those commits on upstream/main, and use its parent SHA as the baseline.
This skill ports across a shared Microsoft VSCode baseline. Two independent signals indicate the baseline relationship:
version and distro in package.json on main vs upstream/main. If both match, the repos share a baseline — proceed. A Merge 1.NNN.0 / Merge rel-* commit in the range is then a reconciliation merge that brought vscode-server up to the baseline Positron already has; skip the merge itself but still port the feature/bugfix PRs interleaved around it. If version or distro differ, the repos have diverged — stop and sync the Microsoft baseline before porting anything.The script outputs all new commits on upstream/main since the baseline, with file stats per candidate.
If the user asks to pull one specific PR or issue (rather than "pull everything new"), run the backlog check before porting it. The single requested PR is rarely the only thing waiting upstream, and silently porting just that one leaves the rest of the backlog undiscovered.
.claude/skills/positron-pull-vscode-server/scripts/check-backlog.shThe script auto-derives the baseline from the most recent "upstream merge from vscode-server" commit (searching all refs, since that merge often lives on a dedicated pull-vscode-server branch, not main). Pass an explicit <baseline-sha> to override.
The script already filters two classes of merge so they are never candidates:
Merge 1.NNN.0 from upstream, Merge rel-*, merge/1.NNN.0 branches). These are reconciliation merges that bring vscode-server up to a Microsoft VSCode baseline Positron tracks independently. They are not portable PRs, are never considered, and must not appear in the PR body's "Considered but not included" list.update-extension-* (rstudio.rstudio-workbench) bumps when Positron is not behind. The script compares the rstudio.rstudio-workbench version in product.json on main vs upstream/main. If Positron's version is equal or newer, the bump is already covered and is dropped. Only when Positron is behind does the script keep update-extension-* as a candidate worth considering.It then lists the remaining candidate merges and prints triage guidance. For those:
version-bump and .github//Jenkinsfile-only PRs are vscode-server tooling — skip. What's left is portable source changes.Keep a short record of every candidate PR you triaged but did not port and the one-line reason (tooling-only, back-ported and already in Positron, user scoped it out, etc.). This record feeds the PR body in Step 5. Do not record the filtered-out baseline merges — they were never candidates.
For each candidate, git show <SHA> to read the full diff, then port it unless:
Jenkinsfile, jenkins/, .github/ only)Do not cherry-pick — line numbers differ between the repos and cherry-pick conflicts are harder to resolve than manual application.
git show <upstream-SHA> # read the diff
# open the Positron file and apply the equivalent changeMarker rules:
// --- Start PWB: ... --- / // --- End PWB ---): copy exactly as they appear in the upstream diff. Do not rename them to Positron markers.// --- Start Positron --- / // --- End Positron ---): use only when Positron needs to add or change something on top of the PWB change. Do not use them to wrap changes that came from vscode-server.format.mts (run in Step 4) may re-indent a marker comment to match its surrounding scope — e.g. an // --- End PWB --- placed just before an array element gets indented one level deeper than it sits in the upstream diff. That is correct: let the formatter win on indentation. "Copy exactly" governs the marker text and placement, not whitespace the formatter owns.
npm run build-ps # check daemon status; if watch-client is stopped, run build-start first
npm run build-check # TypeScript errors
npm run precommit -- <file1> <file2> ... # lint and formattingThe TypeScript-checking daemon (watch-client) is often stopped; build-check only reports the latest cycle, so start the daemons with npm run build-start before relying on its output.
build-check reports errors across the whole project, including pre-existing failures in extensions you didn't touch (e.g. positron-data-driver-duckdb "Cannot find module" errors from build ordering). Verify the files you ported compile clean; ignore pre-existing errors in untouched code.
Fix precommit issues only in lines you touched. Do not fix pre-existing warnings in unrelated parts of the file — those belong in a separate commit. Before committing, run git status and exclude any unrelated churn a build daemon may have introduced (e.g. line-ending rewrites in a package-lock.json you never opened) — git checkout -- <file> to drop it.
Bundle everything into one commit. Keep the message focused on what's being ported and why — do not include QA notes or e2e test tags (those belong in the PR body only):
git commit -m "upstream merge from vscode-server
Brings in:
- rstudio/vscode-server#N: <description>
<optional: 1-2 short paragraphs of context, e.g. who/what is affected>"After the commit lands and verification passes, ask the user whether to create a PR using the positron-pr-helper skill — do not push or open the PR until they confirm.
If they say yes, invoke positron-pr-helper. Always include @:workbench @:web @:jupyter in the QA tags. Then look at the ported diffs and add any other tags that match the affected areas — positron-pr-helper fetches the current list from test/e2e/infra/test-runner/test-tags.ts (or run .claude/skills/positron-pr-helper/scripts/fetch-test-tags.sh list directly). Pick tags conservatively — only add ones that genuinely match what changed. The mandatory three (@:workbench @:web @:jupyter) already cover the PWB surface area; additional tags are for routing extra coverage at the specific subsystem that was touched.
Keep the PR body lean. Lead with Fixes #<positron-issue> and a one-line "Upstream merge from vscode-server, bringing in rstudio/vscode-server#N." Do not restate the problem and solution — the linked Positron issue already describes the problem and the upstream PR already describes the fix. Restating them just duplicates the issue.
The PR body must include a "Considered but not included" section listing the candidate PRs from the Step 1b backlog that were triaged but left out. Format it as a two-column table: the reason in the first column, the vscode-server PRs as a <ul><li>…</li></ul> bullet list in the second (group PRs that share a reason into one row). GitHub-flavored markdown does not render native list syntax inside a table cell, so use inline <ul>/<li> tags.
Other commits on `upstream/main` since the last pull (#<positron-merge-pr>) were triaged and left out:
| Reason | Commits |
| --- | --- |
| Already implemented in Positron (#<positron-pr>) | <ul><li>rstudio/vscode-server#NNN (short description)</li></ul> |
| rstudio.rstudio-workbench bumps; Positron's `product.json` already pins a newer version | <ul><li>rstudio/vscode-server#NNN</li><li>rstudio/vscode-server#NNN</li></ul> |
| CI automation (`.github/` / `Jenkinsfile` only) | <ul><li>rstudio/vscode-server#NNN</li></ul> |Reference rules for the table and the rest of the body:
rstudio/vscode-server#NNN, including each item in a bullet list — a bare #NNN on a posit-dev/positron PR auto-links to a Positron issue of that number, mislinking to something unrelated.#NNN that belong in the body are genuine Positron references: the issue being fixed, the prior upstream-merge PR, and any "already implemented in Positron" links.since the last pull (#13497)), not a vscode-server PR number. Find it with gh pr list --repo posit-dev/positron --state merged --search "upstream merge from vscode-server in:title" --limit 1.If the backlog was empty (nothing portable beyond what was ported), state that explicitly rather than omitting the section. This makes the scope decision auditable — a reviewer can see the full delta was reviewed, not just the part that landed.
After the PR is open (or after the user declines to create one), ask the user how the skill worked for them and whether anything about the workflow should be changed. If they suggest changes, edit SKILL.md directly so future runs incorporate the feedback.
| Mistake | Fix |
|---|---|
Renaming // --- Start PWB: ... --- to // --- Start Positron --- | Keep PWB markers exactly as upstream. Positron markers are only for additions on top. |
| Cherry-picking instead of applying diffs manually | No shared git ancestry — cherry-pick conflicts are worse than manual application |
| Fixing pre-existing lint warnings in unrelated lines | Only fix issues in code you actually changed |
| Porting only the one PR the user named, missing the backlog | Run check-backlog.sh (Step 1b) and surface the full portable list before deciding scope |
Treating Merge 1.NNN.0 as out-of-scope divergence when baselines match | Compare version/distro in package.json — matching means it's a reconciliation merge, not a divergence; the PRs around it are still portable |
b87c504
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.