A lens from
git blameto release version. See which release first shipped any line of code, right in your editor.
π’ v1.2.0 β the line under your cursor first shipped in v1.2.0
π’ Unreleased β committed, but not in any release tag yet
π’ Uncommitted β working-tree edit
π’ Limited history β shallow clone; can't determine reliably
A single status-bar item, updated as you move the cursor. No new panels, no hover popups, no editor decorations. Just one quiet line that answers the question: "in which release did this line first reach users?"
ShipLens is published to both major marketplaces, so it's available in every common VSCode-compatible editor:
| Editor | Marketplace |
|---|---|
| VSCode | VSCode Marketplace |
| Cursor / VSCodium / Theia / Gitpod | Open VSX Registry |
| Any IntelliJ-Platform IDE (2025.1+) | JetBrains Marketplace |
JetBrains IDE coverage β verified compatible: IntelliJ IDEA (Ultimate + Community), PyCharm (Pro + Community), GoLand, WebStorm, RubyMine, CLion, Rider, DataGrip, PhpStorm, RustRover, DataSpell, Android Studio, MPS. Not supported: AppCode (deprecated upstream), JetBrains Gateway, JetBrains Client, Code With Me Guest.
Or in your editor: open the Extensions panel (Cmd+Shift+X / Ctrl+Shift+X), search ShipLens, click Install. Both marketplaces ship the same build, byte-for-byte.
CLI alternative (works in any VSCode-compatible editor):
code --install-extension Ender-Wang.shiplens # VSCode
cursor --install-extension Ender-Wang.shiplens # CursorRequires VSCode 1.85+ (or any compatible fork). Works alongside GitLens.
git blame answers who last touched a line. Tools like GitLens make that
information beautifully accessible. But none of them answer the equally
important question β which release first shipped that change to users?
You can piece it together with git tag --contains, git describe, or a
trip to the Changelog, but each of those means leaving the editor and
breaking your reading flow. ShipLens collapses that lookup into a glance at
the status bar.
| Dimension | GitLens | ShipLens |
|---|---|---|
| Core question | Who changed this line, when | Which release shipped this line |
| Primary UI | Inline blame, hover, side panels | A single line in the status bar |
| Performance focus | Whole-file blame, rich UI | Single-line query, minimal noise |
| Configuration surface | High | Minimal |
| Coexistence | β | Fully compatible; runs alongside GitLens |
ShipLens is intentionally narrow. If GitLens is the microscope, ShipLens is the timestamp on the slide.
ShipLens shows a tag only when three things are true:
git blame -L N,N -- filereports commitCas the line's last author.git tag --contains Cincludes tagT.Tis the earliest non-pre-release tag in that set, ordered by the committer date of the commit each tag points to.
Steps 1 and 2 are pure git β the same machinery that powers GitLens, GitHub blame, and git rev-list. We don't reinterpret them. Step 3 is the only judgment call: we sort by committer date because tag creation date can lag the actual release (retroactive tagging), author date can predate the merge by months, and topological order isn't well-defined when commits are cherry-picked across release branches. Pre-releases are filtered before the pick via shiplens.tagInclude / shiplens.tagExclude (defaults exclude *-rc*, *-beta*, *-alpha*, *-pre*, *-dev*, *-snapshot*).
When any of those assumptions doesn't hold, ShipLens says so explicitly rather than guess: Uncommitted (working-tree edit), Unreleased (no containing tag yet), Limited history (shallow clone, ancestry can't be traversed reliably).
You can reproduce the algorithm by hand in any repo:
git blame -L N,N -- file # β commit SHA
git tag --contains <sha> # β candidate tags
for t in <candidates>; do # β committer dates
echo -n "$t "; git log -1 --format='%cI' "$t"
done | sort -k2The first non-pre-release line in that sorted output is what the status bar shows. If they ever disagree, that's a bug β please open an issue.
- Code archaeology β spot a critical line and immediately know which release it first appeared in. No editor switch, no Changelog hunting.
- Bug triage β a user reports "it broke in v1.3.0"; jump to the suspect line and verify whether it was indeed introduced there.
- Regression test scoping β use the first-release tag to decide which versions need re-testing for a given change.
- Documentation and review β cite a release version directly from the status bar when explaining a change to teammates.
- Multi-repo workflows β in microservice or multi-repo setups, quickly correlate a change in the current repo with its release graph.
For agent / CLI workflows (Cursor CLI, Claude Code CLI, GitHub Copilot CLI, etc.) where the editor isn't open, ShipLens ships a Cursor Agent Skill that teaches your agent the same algorithm. Install it once:
mkdir -p ~/.cursor/skills
cp -r skills/shiplens ~/.cursor/skills/Then ask your agent things like:
- "Which release first shipped line 42 of
src/auth.ts?" - "In which version did the regression on line 88 of this file land?"
- "What tag contains commit abc1234?"
The skill auto-activates on those phrasings β no need to mention "ShipLens" by name. It runs the exact same git blame β git tag --contains β first by committer date pipeline as the editor extension, with the same default filters.
The canonical skill source lives at skills/shiplens/SKILL.md in this repo. It's updated alongside extension releases when defaults change.
Available on the VSCode Marketplace, Open VSX Registry, and JetBrains Marketplace.
- First-release tag for the current line, displayed in the status bar.
- Tooltip with commit SHA, summary, author, and tag date.
- Tag include/exclude glob configuration (pre-releases filtered by default).
- Multi-root workspace isolation.
- Graceful degradation for
Uncommitted,Unreleased, andLimited history.
- Click status bar to open the corresponding GitHub / GitLab tag page.
- Multi-line selection: show the earliest and latest release across the range.
- Monorepo tag-prefix routing (e.g.,
frontend-v*vs.backend-v*). - Background tag-DAG index for instant lookups on large repos.
- Issue / PR linking through commit message references (
Fixes #123β release). - File-level release timeline view (every release in which the file changed).
- CI/CD signal hookup β tag β pipeline status alongside the version.
- JetBrains plugin reusing the same core.
- Optional integration with GitLens' blame data source.
The defaults work for most repos. The full set of v0.1 settings:
| Setting | Default | Description |
|---|---|---|
shiplens.tagInclude |
* |
Glob passed to git tag --contains. |
shiplens.tagExclude |
["*-rc*", "*-beta*", "*-alpha*", "*-pre*", "*-dev*", "*-snapshot*", "rescue/*"] |
Patterns dropped after the include filter. Covers common pre-release suffixes and the rescue/* namespace some teams use for internal hotfixes. |
shiplens.sortBy |
committerDate |
How candidate tags are ordered. |
shiplens.debounceMs |
150 |
Delay between cursor movement and the next query. |
shiplens.followRenames |
false |
Pass --follow to git blame. |
shiplens.statusBar.alignment |
right |
Status bar position. |
This is an npm-workspaces monorepo:
packages/coreβ@shiplens/core, the editor-agnostic library that does the git work. Pure TypeScript, no editor dependencies.packages/vscode-extensionβshiplens, the VSCode extension shell. UI, configuration, and event wiring; no git logic of its own.packages/jetbrains-pluginβshiplens-jetbrains, a Kotlin port of the algorithm + IntelliJ-Platform integration (status bar, settings, listeners). Single-JAR, no Node runtime, no IPC. Mirrors@shiplens/core's structure file-for-file for easy lockstep maintenance.
nvm use # picks up Node 22 from .nvmrc
npm install
npm run buildOpen this folder in VSCode and press F5 ("Run Extension"). A new window
opens with ShipLens loaded. npm run watch keeps the bundle fresh while you
iterate; reload the host window (Cmd+R) after a change.
npm run package # produces packages/vscode-extension/shiplens.vsix
npm run install:vsix # runs `code --install-extension ... --force`Or install from the VSCode UI: Extensions panel β β¦ menu β Install
from VSIXβ¦ β pick packages/vscode-extension/shiplens.vsix.
To uninstall: code --uninstall-extension Ender-Wang.shiplens (or via the
Extensions panel).
MIT β see LICENSE.