Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<p align="center">
<img src="assets/logo.svg" alt="Version Sentinel" width="200" />
<img src="assets/hero.png" alt="Version Sentinel — no dependency ships unverified" width="864" />
</p>

<h1 align="center">version-sentinel</h1>

<p align="center">
<a href="https://github.com/KSEGIT/Version-Sentinel/releases/latest"><img src="https://img.shields.io/github/v/release/KSEGIT/Version-Sentinel?color=blue" alt="Release" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/github/license/KSEGIT/Version-Sentinel" alt="License: MIT" /></a>
Expand Down
173 changes: 173 additions & 0 deletions assets/hero.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 1536px; height: 768px; overflow: hidden; }
body {
font-family: -apple-system, "SF Pro Display", "Helvetica Neue", sans-serif;
background:
radial-gradient(ellipse 900px 700px at 78% 50%, rgba(3,216,248,0.10), transparent 60%),
radial-gradient(ellipse 1200px 900px at 50% 120%, #141934 0%, #0b1026 70%);
background-color: #0b1026;
position: relative;
}
/* dot grid */
.dots {
position: absolute; inset: 0;
background-image: radial-gradient(rgba(148,163,184,0.13) 1px, transparent 1px);
background-size: 32px 32px;
mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black 30%, transparent 75%);
-webkit-mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black 30%, transparent 75%);
}
.specks { position: absolute; border-radius: 50%; background: #7dd3fc; }

.layout {
position: relative; z-index: 2;
display: flex; align-items: center;
height: 100%; padding: 0 72px; gap: 40px;
}

/* ---------- left ---------- */
.left { flex: 1 1 56%; display: flex; flex-direction: column; gap: 36px; }

.wordmark { display: flex; align-items: center; gap: 18px; }
.wordmark svg { filter: drop-shadow(0 0 10px rgba(3,216,248,0.55)); }
.wordmark h1 {
font-size: 58px; font-weight: 800; letter-spacing: 0.5px; color: #f1f5f9;
}
.tagline {
margin-top: 10px; font-size: 24px; color: #94a3b8; font-weight: 500; letter-spacing: 0.3px;
}
.tagline em { font-style: normal; color: #03d8f8; }

.terminal {
background: rgba(26,33,64,0.82);
border: 1px solid rgba(148,163,184,0.16);
border-radius: 14px;
box-shadow: 0 24px 60px rgba(0,0,0,0.45), 0 0 0 1px rgba(3,216,248,0.05);
overflow: hidden;
max-width: 780px;
}
.termbar {
display: flex; align-items: center; gap: 8px;
padding: 13px 16px;
background: rgba(11,16,38,0.65);
border-bottom: 1px solid rgba(148,163,184,0.12);
}
.termbar .dot { width: 12px; height: 12px; border-radius: 50%; }
.termbar .r { background: #f87171; } .termbar .y { background: #fbbf24; } .termbar .g { background: #4ade80; }
.termbar .title {
margin-left: 12px; font-family: "SF Mono", Menlo, monospace;
font-size: 13px; color: #64748b;
}
.termbody {
padding: 22px 24px 26px;
font-family: "SF Mono", Menlo, monospace;
font-size: 19.5px; line-height: 2.05; white-space: nowrap;
}
.cmd { color: #e2e8f0; }
.cmd .prompt { color: #03d8f8; font-weight: 700; }
.blocked { color: #f87171; }
.muted { color: #7d8aa5; }
.rec { color: #03d8f8; }
.ok { color: #4ade80; font-weight: 700; }

/* ---------- right ---------- */
.right { flex: 1 1 44%; position: relative; height: 640px; }

.orbit-ring {
position: absolute; border: 1px solid rgba(3,216,248,0.14); border-radius: 50%;
}
.ring1 { width: 460px; height: 460px; left: 70px; top: 90px; }
.ring2 { width: 580px; height: 580px; left: 10px; top: 30px; border-color: rgba(3,216,248,0.08); }

.shield-disc {
position: absolute; left: 150px; top: 170px;
width: 300px; height: 300px; border-radius: 50%;
background: radial-gradient(circle at 50% 38%, #232c52 0%, #161d3c 70%);
border: 2px solid rgba(3,216,248,0.55);
box-shadow:
0 0 60px rgba(3,216,248,0.35),
0 0 140px rgba(3,216,248,0.18),
inset 0 0 40px rgba(3,216,248,0.10);
display: flex; align-items: center; justify-content: center;
}
.shield-disc img { width: 205px; height: 205px; }

.pill {
position: absolute;
display: flex; align-items: center; gap: 10px;
background: rgba(26,33,64,0.92);
border: 1px solid rgba(148,163,184,0.22);
border-radius: 999px;
padding: 10px 20px;
font-family: "SF Mono", Menlo, monospace;
font-size: 18px; font-weight: 600; color: #e2e8f0;
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.pill .pd { width: 12px; height: 12px; border-radius: 50%; }
.npm { left: 30px; top: 118px; } .npm .pd { background: #cb3837; }
.pypi { left: 385px; top: 60px; } .pypi .pd { background: #3775a9; }
.cargo { left: 420px; top: 505px; } .cargo .pd { background: #dea584; }
.nuget { left: 55px; top: 520px; } .nuget .pd { background: #2b8fd4; }
</style>
</head>
<body>
<div class="dots"></div>
<div class="specks" style="width:3px;height:3px;left:120px;top:90px;opacity:.7"></div>
<div class="specks" style="width:2px;height:2px;left:1420px;top:120px;opacity:.5"></div>
<div class="specks" style="width:2px;height:2px;left:1380px;top:660px;opacity:.6"></div>
<div class="specks" style="width:3px;height:3px;left:80px;top:690px;opacity:.4"></div>
<div class="specks" style="width:2px;height:2px;left:760px;top:60px;opacity:.5"></div>

<div class="layout">
<div class="left">
<div>
<div class="wordmark">
<svg width="52" height="52" viewBox="0 0 24 24" fill="none">
<path d="M12 2l8 3.5v5.2c0 5.1-3.4 9.8-8 11.3-4.6-1.5-8-6.2-8-11.3V5.5L12 2z"
stroke="#03d8f8" stroke-width="1.8" fill="rgba(3,216,248,0.12)"/>
<circle cx="11" cy="10.5" r="3.1" stroke="#03d8f8" stroke-width="1.7"/>
<line x1="13.3" y1="12.9" x2="16" y2="15.6" stroke="#03d8f8" stroke-width="1.9" stroke-linecap="round"/>
</svg>
<h1>Version Sentinel</h1>
</div>
<p class="tagline">No dependency ships <em>unverified</em>.</p>
</div>

<div class="terminal">
<div class="termbar">
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
<span class="title">version-sentinel — PreToolUse hook</span>
</div>
<div class="termbody">
<div class="cmd"><span class="prompt">$</span> npm install lodash@4.17.20</div>
<div class="blocked">✗ BLOCKED version-sentinel — no fresh version check on record</div>
<div class="muted">→ lookup npmjs.com/package/lodash · latest 4.18.1</div>
<div class="rec">→ bash scripts/vs-record.sh npm lodash 4.18.1 https://www.npmjs.com/package/lodash</div>
<div class="ok">✓ VERIFIED — install allowed</div>
Comment on lines +146 to +150

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
curl -fsSL https://registry.npmjs.org/lodash | jq -r '."dist-tags".latest'

Repository: KSEGIT/Version-Sentinel

Length of output: 168


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate relevant files =="
git ls-files | grep -E '(^assets/hero\.html$|(^README\.md$|(^scripts/vs-record\.sh$))' || true

echo "== inspect assets/hero.html around relevant lines =="
sed -n '130,160p' assets/hero.html

echo "== inspect scripts/vs-record.sh if present =="
if [ -f scripts/vs-record.sh ]; then
  sed -n '1,120p' scripts/vs-record.sh
else
  echo "scripts/vs-record.sh not found"
fi

echo "== references to recorded lodash version and vs-record command in repo =="
rg -n "lodash@4\.17\.20|lodash@4\.17\.21|lodash@4\.18\.1|vs-record|version-sentinel|latest 4\.17" .

Repository: KSEGIT/Version-Sentinel

Length of output: 34683


Use the current lodash version and the required recording command.

The flow shows latest 4.17.21, but npm marks 4.18.1 as latest. Use npm install lodash@4.18.1 for the requested version, and replace vs-record npm lodash 4.17.21 with bash scripts/vs-record.sh npm lodash 4.18.1 <source-url> so the example matches the documented workflow. Regenerate assets/hero.png because README.md renders it.

Proposed fix
-          <div class="cmd"><span class="prompt">$</span> npm install lodash@4.17.20</div>
+          <div class="cmd"><span class="prompt">$</span> npm install lodash@4.18.1</div>
           <div class="blocked">✗ BLOCKED version-sentinel — no fresh version check on record</div>
-          <div class="muted">→ lookup npmjs.com/package/lodash · latest 4.17.21</div>
-          <div class="rec">→ vs-record npm lodash 4.17.21 &lt;source-url&gt;</div>
+          <div class="muted">→ lookup npmjs.com/package/lodash · latest 4.18.1</div>
+          <div class="rec">→ bash scripts/vs-record.sh npm lodash 4.18.1 &lt;source-url&gt;</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class="cmd"><span class="prompt">$</span> npm install lodash@4.17.20</div>
<div class="blocked">✗ BLOCKED version-sentinel — no fresh version check on record</div>
<div class="muted">→ lookup npmjs.com/package/lodash · latest 4.17.21</div>
<div class="rec">→ vs-record npm lodash 4.17.21 &lt;source-url&gt;</div>
<div class="ok">✓ VERIFIED — install allowed</div>
<div class="cmd"><span class="prompt">$</span> npm install lodash@4.18.1</div>
<div class="blocked">✗ BLOCKED version-sentinel — no fresh version check on record</div>
<div class="muted">→ lookup npmjs.com/package/lodash · latest 4.18.1</div>
<div class="rec">bash scripts/vs-record.sh npm lodash 4.18.1 &lt;source-url&gt;</div>
<div class="ok">✓ VERIFIED — install allowed</div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/hero.html` around lines 146 - 150, Update the lodash example in
assets/hero.html to use version 4.18.1 consistently, including the displayed
latest version and installation command. Replace the recording step with the
documented bash scripts/vs-record.sh workflow using lodash 4.18.1 and the source
URL, then regenerate assets/hero.png so the README-rendered image matches.

Source: Coding guidelines

</div>
</div>
</div>

<div class="right">
<div class="orbit-ring ring2"></div>
<div class="orbit-ring ring1"></div>
<div class="shield-disc">
<svg width="200" height="200" viewBox="0 0 24 24" fill="none">
<path d="M12 2l8 3.5v5.2c0 5.1-3.4 9.8-8 11.3-4.6-1.5-8-6.2-8-11.3V5.5L12 2z"
stroke="#03d8f8" stroke-width="1.1" fill="rgba(3,216,248,0.10)"/>
<circle cx="11" cy="10.5" r="3.1" stroke="#03d8f8" stroke-width="1.0"/>
<line x1="13.3" y1="12.9" x2="16" y2="15.6" stroke="#03d8f8" stroke-width="1.2" stroke-linecap="round"/>
</svg>
</div>
<div class="pill npm"><span class="pd"></span>npm</div>
<div class="pill pypi"><span class="pd"></span>PyPI</div>
<div class="pill cargo"><span class="pd"></span>Cargo</div>
<div class="pill nuget"><span class="pd"></span>NuGet</div>
</div>
</div>
</body>
</html>
Binary file modified assets/hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions docs/marketplaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Submission status legend:
| Kimi Code | `/plugins install https://github.com/KSEGIT/Version-Sentinel` (or a local path); custom catalog `kimi-marketplace.json` at repo root for `/plugins marketplace <url>` | No official Kimi gallery known — self-hosted catalog | **ready-in-repo** | Optionally verify the `/plugins marketplace <url>` flow in the TUI (install TUI flow still unverified per `docs/e2e-checklist.md`) |
| Gemini CLI | `gemini extensions install https://github.com/KSEGIT/Version-Sentinel`, then `bash ~/.gemini/extensions/version-sentinel/platforms/gemini/setup.sh` | geminicli.com/extensions gallery — **fully automated daily crawler**, no PR and no form | **requires-owner-form** (one repo-setting change) | Add the GitHub topic `gemini-cli-extension` to the repo's About section; the crawler lists it within ~24h |
| OpenAI Codex | `codex plugin marketplace add KSEGIT/Version-Sentinel` → `codex plugin add version-sentinel` (works today from GitHub) | Universal OpenAI Plugins Directory (ChatGPT + Codex) | **requires-owner-form** (portal, now self-serve) | Verify developer identity on the OpenAI Platform, then submit via the plugin submission portal (see below) |
| GitHub Copilot CLI | Once listed: `copilot plugin marketplace add github/awesome-copilot` → `copilot plugin install version-sentinel@awesome-copilot` (verified installable — the awesome-copilot intake smoke test installs from this repo's root `plugin.json` via an ephemeral marketplace) | awesome-copilot external plugin marketplace (`plugins/external.json`, review-workflow gated) | **requires-owner-form** (issue submitted) | Track submission issue [github/awesome-copilot#2598](https://github.com/github/awesome-copilot/issues/2598) — opened 2026-08-09, passed all automated quality gates (`ready-for-review`), awaiting maintainer `/approve`; on approval a bot PR adds the entry automatically |
| GitHub Copilot in VS Code | Repo-based: `.github/` + `.agents/skills/` are picked up when this repo is the workspace, or copy them into yours | None | **no-marketplace** | None — distribution is "use this repo as (part of) your workspace" |
| Zed | Repo-based: `AGENTS.md` + `.agents/skills/` + `docs/zed.md` (static-permissions approximation; no hook support) | None | **no-marketplace** | None |

Expand Down Expand Up @@ -124,6 +125,38 @@ Submission status legend:
- Sources: [Codex plugins overview](https://developers.openai.com/codex/plugins),
[Submit plugins — OpenAI Developers](https://developers.openai.com/plugins/deploy/submission).

### GitHub Copilot CLI — awesome-copilot marketplace

- The [github/awesome-copilot](https://github.com/github/awesome-copilot)
collection lists external plugins in `plugins/external.json`; public
contributors must **not** PR that file directly — submission is an
issue-form workflow (`[External Plugin]:` issue) with automated intake
(`vally lint` + a Copilot CLI install smoke test + version/ref-sha
consistency gates), then maintainer `/approve` opens the listing PR.
- Submitted 2026-08-09 as
[github/awesome-copilot#2598](https://github.com/github/awesome-copilot/issues/2598)
for `version-sentinel` 0.4.1 (ref `version-sentinel-v0.4.1`, sha
`f3d5349685f22c96069383a559ed741b42bed508`, plugin at repo root). All
blocking gates passed; the issue is `ready-for-review`.
- Gotcha hit during intake: leaving `/` in the form's *Plugin path* field
produces `source.path: "/"`, which the Copilot CLI smoke test rejects
("Plugin path escapes repository directory") — leave the field empty for
a root plugin.
- Non-blocking spec warnings remain: our `plugin.json` carries Claude
Code top-level fields (`skills`, `agents`, `commands`, `userConfig`)
outside Agent Plugins v1.0.0. They are required by the other platforms;
do not "fix" them for this listing.
- After approval, a nightly job marks approved listings as due for re-review
every six months; a maintainer then performs the actual review on the
original issue (`/re-review-keep` et al. are maintainer commands).
- The gates can be rehearsed locally before any resubmission: clone
awesome-copilot, `cd` into it, verify the upstream version of
`@github/copilot` (currently 1.0.78), record it with
`bash scripts/vs-record.sh npm @github/copilot 1.0.78 https://www.npmjs.com/package/@github/copilot`,
then run `npm install` and
`node eng/external-plugin-quality-gates.mjs --plugin-json '<entry json>'`
with `copilot` on PATH (`@github/copilot` npm package).
Comment on lines +152 to +158

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Document the required version-audit step before npm install.

This procedure runs an install command without the required upstream-version verification and vs-record.sh record when Version Sentinel blocks the command. The intake notes confirm that Version Sentinel blocks install commands until a fresh, source-cited check is recorded. (github.com)

Add the preflight step before npm install, and make the working directory explicit.

As per coding guidelines, dependency install commands require upstream version verification and a bash scripts/vs-record.sh <ecosystem> <pkg> <version> <source-url> record when blocked.

Proposed wording
-clone awesome-copilot, `npm install`, and run
+clone awesome-copilot, verify dependency versions against their upstream
+registries, record blocked targets with
+`bash scripts/vs-record.sh <ecosystem> <pkg> <version> <source-url>`, then run
+`npm install` and
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/marketplaces.md` around lines 151 - 154, Update the local gate-rehearsal
procedure in the marketplace documentation to add the required upstream version
verification and corresponding bash scripts/vs-record.sh record before npm
install, using the appropriate ecosystem, package, version, and source URL. Make
the working directory explicit by instructing the user to run the commands from
the cloned awesome-copilot directory, while preserving the existing quality-gate
command.

Sources: Coding guidelines, MCP tools


### GitHub Copilot in VS Code / Zed

Neither platform has a plugin marketplace or directory for this kind of
Expand Down