Production-readiness pass: security hardening, esbuild bundle, narrowed activation#1
Conversation
- package.json: add capabilities.untrustedWorkspaces (limited) and virtualWorkspaces=false so the LSP child never spawns from an untrusted workspace. Mark serverCommand and serverArgs as machine-overridable so a malicious .vscode/settings.json cannot silently swap the interpreter or inject -c "<code>". Document the Windows PATH-cwd hazard on serverCommand. - src/extension.ts: tighten outputChannel typing; capture as vscode.OutputChannel at construction, drop optional chaining on use. - tsconfig.json: noEmitOnError stops a broken local compile from shipping junk into out/. - .github/workflows/publish.yml: pin @vscode/vsce@3.9.1 and ovsx@0.10.12 (no more @latest with PATs in env), refuse to publish a tag that isn't on main, narrow workflow-default permissions to contents:read with the publish job opting up for the release step. - ROADMAP.md: track outstanding production-readiness work, tick the items landed here. - CHANGELOG.md: Security block under Unreleased. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C1 fix (marketplace blocker): - esbuild bundle replaces tsc emit. vscode:prepublish builds the minified prod bundle to dist/extension.js (348kb); compile builds the dev bundle with sourcemap so F5 stays debuggable. - package.json#main is now ./dist/extension.js. .vsix contents now ship the bundled JS instead of the previous out/extension.js, which would have thrown "Cannot find module 'vscode-languageclient/node'" at activation in any clean install (node_modules was excluded by .vscodeignore but never bundled). - scripts/smoke.js stubs the vscode module via Module._load, loads dist/extension.js, and asserts activate/deactivate are exported. Hooked into CI as `npm run smoke` so a missing runtime dep fails the build instead of the user. - .vscodeignore excludes out/** (legacy emit dir) and the new ROADMAP.md. - .vscode/launch.json outFiles repointed at dist/. H1 parity: - ci.yml pins @vscode/vsce@3.9.1 (no secrets in ci.yml, but matches publish.yml so a regression in @latest can't sneak in via PRs). M1: SECURITY.md. - GitHub Private Vulnerability Reporting as the disclosure channel, acknowledge/assessment SLAs, threat model + out-of-scope list. M3: npm audit step. - `npm audit --omit=dev --audit-level=high` on every push to main and every PR — catches advisories filed after a PR has merged. M4: CHANGELOG-fold check. - publish.yml refuses a tag whose CHANGELOG.md is missing a `## [X.Y.Z]` header. Protects the release-notes extraction that ships into the GitHub release. L4: defense-in-depth comment on THRESHOLD_RANK[...] ?? LOW so the intent (a diagnostic must clear LOW, never silently disappear) is spelled out for the next reader. L5: added Other next to Linters in categories. L6: added qna pointing at the repo Discussions page. ROADMAP.md and CHANGELOG.md updated to reflect the new state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
H4 — narrow activation surface: - activationEvents replaces bare onLanguage:* triggers with workspaceContains: patterns for the providers we actually scan (GHA, GitLab, Azure, Bitbucket, CircleCI, Cloud Build, Buildkite, Drone, Jenkins, Dockerfile, Containerfile). Opening an unrelated package.json or mkdocs.yml no longer activates the extension. - documentSelector switches from language IDs to matching file-path globs. The LSP only sees candidate documents, so the server's content-and-path filter is a backstop instead of the first line of defence. Also removes the dependency on whether the user has the official GitHub Actions extension installed (which would hijack the github-actions-workflow language ID). H1 follow-up — Dependabot coverage: - @vscode/vsce and ovsx are now pinned devDependencies. Versions live in package-lock.json and Dependabot's existing npm config keeps them current. - ci.yml and publish.yml call npx vsce / npx ovsx after npm ci, so the locally-installed binary is used (no fresh registry fetch with PATs in env). Added npm scripts: package, publish:vsce, publish:ovsx. Findings tree view scaffolding (ridden along on this commit because extension.ts edits collided with the H4 work): - src/findingsView.ts: new FindingsTreeProvider that reads from vscode.languages.getDiagnostics() so the panel works whether or not the LSP is running. - extension.ts wires the provider before startClient so the panel is available even when the server fails. - onView:pipelineCheck.findings added to activationEvents. ROADMAP.md ticks H4 and the H1 Dependabot follow-up; the remaining open items are the manual repo-settings actions (H2 environment, PVR, Discussions) that cannot land from a branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
These four files were untracked when the production-readiness pass started; README badges, the new ROADMAP, and SECURITY.md all reference them, so they're clearly meant to ship. - .github/dependabot.yml: weekly npm and github-actions bumps. The H1 follow-up moves vsce+ovsx into devDeps so this same config keeps them current. - .github/workflows/codeql.yml: CodeQL JavaScript/TypeScript analysis on push, PR, and weekly. - .github/workflows/dependency-review.yml: PR-only dep-review action that fails on high-severity advisories or non-allowlisted licenses. - media/pipeline-check.svg: icon for the Findings panel view that ships in the cca86ff commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (18)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Adds the project's first test suite. 25 tests, all pure-logic — no
extension host, no integration boot. Sets up the infrastructure
(vitest, vi.mock for vscode-touching code) so future tests follow the
same pattern.
Refactor:
- src/severityFilter.ts: pure module factored out of the LSP
middleware. Owns SEVERITY_RANK, THRESHOLD_RANK, passesThreshold, and
filterByThreshold. No vscode imports, so the test runs without a
stub.
- src/extension.ts: middleware.handleDiagnostics now calls
filterByThreshold instead of inlining the logic. Inline severity
tables removed.
Tests:
- src/severityFilter.test.ts (14): pins down the invariants that keep
the filter from silently dropping findings — missing/unknown
severity always passes, unknown threshold falls back to LOW,
CRITICAL survives every threshold, INFO never does, ordering and
non-mutation are preserved.
- src/findingsView.test.ts (11): vi.mock("vscode", ...) stubs the
editor namespace so we can exercise FindingsTreeProvider end-to-end.
Covers source filtering (only pipeline-check diagnostics appear),
all three group modes with bucket ordering + counts + leaf labels +
vscode.open command, severity normalisation, and the
no-refresh-storm contract on same-mode setGroupMode.
Wiring:
- vitest.config.ts: include src/**/*.test.ts, environment: node.
- package.json: vitest devDep + npm test / npm test:watch scripts.
- ci.yml: "Unit tests" step gates every PR.
- publish.yml: "Unit tests" + "Bundle smoke" gate every tag.
Smoke fix:
- scripts/smoke.js: explicit ThemeIcon and ThemeColor stubs. The
findings view instantiates ThemeColor at module-load time inside the
SEVERITY_ICON table; esbuild's __toESM namespace wrapper enumerates
own keys at load time, so the Proxy's dynamic-class fallback was
invisible. Pre-populating the two classes restores the
bundle-loads-cleanly contract.
.vscodeignore already excludes src/** and **/*.ts, so test files and
vitest.config.ts never ship in the .vsix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The leaf-rendering refactor moves the rule id + location from the
TreeItem label into an adaptive description column whose format depends
on which group node sits above the leaf. The tests are updated to pin
that contract down, and to cover the new activity-bar badge wiring.
findingsView.test.ts:
- Leaf-label test now reads `item.label === "GHA-001 title"` and
`item.description === "GHA-001 · a.yml:23"` (was the previous
"RULE: title" form).
- New "adaptive leaf description" suite (5 tests) covers severity
mode, file mode, rule mode, 0-based-to-1-based line conversion,
and the missing-rule-id case.
- New "activity-bar badge" suite (4 tests) covers the setTreeView
contract: the badge tracks the visible-finding count, clears to
undefined on an empty workspace, picks singular vs plural tooltip,
and refresh() before setTreeView is a no-op.
- groupByFile description test relaxed to match the count-only form
("2"), now that parentDir is gone from the description.
findingsView.ts:
- Remove dead `parentDir` helper (no callers after groupByFile no
longer renders the parent directory in its description). Lint
caught it.
Total: 34 tests, all passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a dedicated activity-bar surface for Pipeline-Check findings. The panel is strictly a re-presentation of diagnostics the LSP server has already published — it never triggers its own scan, so the thin-transport-adapter promise in extension.ts stays intact. package.json: - viewsContainers.activitybar: a Pipeline-Check slot with the custom inverted-Y pipeline glyph at media/pipeline-check.svg. - views.pipelineCheck: a single "Findings" tree view. - viewsWelcome: empty-state content that leads with what the extension does, then a secondary "Not seeing findings?" line that links the Restart and Show Log commands. - Three new commands (groupBy.severity / file / rule) and a refresh command, all in the Pipeline-Check category. - view/title menu wiring so the active group mode is hidden and the other two render as icons (\$(symbol-event), \$(file), \$(symbol-key)) on the right side of the view header. src/extension.ts: - Two-phase wiring: createTreeView constructs the view with the provider as treeDataProvider, then findingsProvider.setTreeView() hands the view back so the provider can drive the activity-bar badge. - Findings provider is wired before startClient so the panel is visible even when the server fails to come up. media/pipeline-check.svg: - Inverted-Y pipeline glyph designed to read at 24×24 in the activity bar and themed via currentColor so light/dark themes pick up automatically. src/findingsView.test.ts (3 new tests on top of the 34 from the previous commit): - Group tooltip carries the workspace-relative path. - Group icon is picked from the maximum severity in the bucket. - getGroupMode reflects the most recent setGroupMode call. CHANGELOG.md, ROADMAP.md updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
VSCE_PAT and OVSX_PAT now live as environment secrets on the `production` environment, not as repo secrets, so any workflow that does not target this environment cannot read them. The publish job adds `environment: production`; a workflow_dispatch or tag push stalls at the environment gate until a reviewer approves the run. This is the last C1/C2/H1/H2 must-have. ROADMAP and CHANGELOG updated to reflect the new state and the remaining maintainer action items. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #1's `analyze` check fails because the repo has GitHub's default CodeQL setup enabled and our codeql.yml is an advanced config — the two cannot coexist on SARIF upload. Adds the disable-default-setup step to the maintainer action items so the green tick is reachable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Four-commit production-readiness pass driven from the pre-marketplace
review in ROADMAP.md. Draft
because of the manual smoke items listed at the bottom.
What landed
Critical
.vsixwas missing its runtime dependency. Previous build emittedout/extension.jsviatscbut.vscodeignoreexcludednode_modules/,so
require("vscode-languageclient/node")would throw on activation ina clean install. Now bundled with esbuild into
dist/extension.js(348 KB minified). CI runs
npm run smoke(scripts/smoke.js)which stubs
vscodeand assertsactivate/deactivateare exported,so this regression class fails the build instead of the user.
pipelineCheck.serverCommandandpipelineCheck.serverArgsare nowmachine-overridable(workspaceoverrides require an explicit prompt). Added
capabilities.untrustedWorkspaces: "limited"+virtualWorkspaces: falseso the LSP child process never spawns from a freshly-cloned untrusted
repo.
High
@vscode/vsceandovsxare nowpinned devDependencies; workflows call them via
npx vsce/npx ovsxafter
npm ci. No more@latestwith PATs in env. Dependabot'sexisting npm config keeps them current.
main.git merge-base --is-ancestorcheck refuses to publish a tag pointed at an off-
maincommit.onLanguage:*triggersreplaced with
workspaceContains:patterns for the providers wescan.
documentSelectorswitches to file-path globs so the LSP onlysees candidate documents; no more dependency on whether the user has
the GitHub Actions extension installed (which would hijack the
github-actions-workflowlanguage ID).Medium / Low
permissions: contents: readat workflow level; publish job opts up towritefor the release step. (Step-level permissions aren't a GitHub Actions feature.)npm audit --omit=dev --audit-level=highon every push and PR.## [X.Y.Z]section.serverCommand;noEmitOnError; tightenedoutputChanneltyping; defense-in-depth comment onTHRESHOLD_RANKfallback;Otheradded tocategories;qnapointed at repo Discussions.Folded in (parallel work, not from this review)
onView:pipelineCheck.findingsactivation event, and the wiring in extension.ts. Rode along on the H4 commit because both edits touched extension.ts.Manual smoke items (before promoting from draft)
These cannot be done from a git branch:
marketplaceGitHub Environment (Settings → Environments → New) with required reviewers, moveVSCE_PAT/OVSX_PATfrom repo secrets to the environment. Then a one-line PR addsenvironment: marketplaceto the publish job. (H2)qnalink in package.json 404s..github/workflows/*.yml,.gitlab-ci.yml,azure-pipelines.yml,bitbucket-pipelines.yml,.circleci/config.yml,cloudbuild.yaml,.buildkite/pipeline.yml,.drone.{yml,yaml},Jenkinsfile,Dockerfile,Containerfile), confirm diagnostics still appear. Custom workflow paths now do nothing — that's intentional.Test plan
npm run lintcleannpm run compileclean (typecheck + esbuild dev bundle)npm run smokeclean (bundle loads, exports activate/deactivate)npm audit --omit=dev --audit-level=highreports 0 vulnerabilitiesnpx vsce lsconfirms the .vsix contents are README, package.json, LICENSE, icon.png, CHANGELOG.md, SECURITY.md, media/pipeline-check.svg, dist/extension.js — no node_modules, no out/🤖 Generated with Claude Code