Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ShipLens

ShipLens

A lens from git blame to release version. See which release first shipped any line of code, right in your editor.

VS Marketplace Open VSX JetBrains Homebrew License: MIT

🚒 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?"

Install

ShipLens runs in three places: VSCode-compatible editors, JetBrains-Platform IDEs, and your terminal.

Surface Where to get it
VSCode VSCode Marketplace
Cursor / VSCodium / Theia / Gitpod Open VSX Registry
Any JetBrains-Platform IDE (2025.1+) JetBrains Marketplace
Terminal (macOS / Linux) brew install ender-wang/tap/shiplens
Terminal (any OS, manual) GitHub Releases β€” shiplens-cli-*.tar.gz / .zip

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.

In an editor, open the Extensions panel (Cmd+Shift+X / Ctrl+Shift+X), search ShipLens, click Install. All editor builds ship the same algorithm, byte-for-byte.

To install an editor extension from the command line:

code --install-extension Ender-Wang.shiplens     # VSCode
cursor --install-extension Ender-Wang.shiplens   # Cursor

To install the CLI:

brew install ender-wang/tap/shiplens             # macOS / Linux (Homebrew)
shiplens line src/auth.ts:42                     # β†’ 🚒 v1.2.0
shiplens commit abc1234 --json                   # stable JSON for scripts / CI

Requires VSCode 1.85+ (or any compatible fork) for the editor extension; the CLI has no runtime dependencies beyond git on PATH. Works alongside GitLens.

Why this exists

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.

How ShipLens differs from GitLens

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.

How it knows (and when it doesn't)

ShipLens shows a tag only when three things are true:

  1. git blame -L N,N -- file reports commit C as the line's last author.
  2. git tag --contains C includes tag T.
  3. T is 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 -k2

The 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.

Use cases

  • 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.

Use it from an agent

The shiplens CLI (see Install) covers scripts, CI jobs, and any agent that can shell out. For Cursor specifically, ShipLens also ships a Cursor Agent Skill that teaches the agent the same algorithm without needing the binary on PATH. 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.

Roadmap

v0.1 β€” shipped

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, and Limited history.

v0.2 β€” planned

  • 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.

v0.3 and beyond

  • 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.

Configuration

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.

Project structure

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.

Development

nvm use            # picks up Node 22 from .nvmrc
npm install
npm run build

Debug in an Extension Development Host

Open 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.

Build a .vsix and install manually

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).

License

MIT β€” see LICENSE.

About

A VSCode/VSX/JetBrains extension/cli that shows the first release version of any line of code, right in the status bar.

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages