diff --git a/.github/workflows/ci-frontend.yml b/.github/workflows/ci-frontend.yml
deleted file mode 100644
index c8350c9..0000000
--- a/.github/workflows/ci-frontend.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Frontend CI
-
-on:
- push:
- branches: [dev]
- paths:
- - 'frontend/**'
- pull_request:
- branches: [dev, master]
- paths:
- - 'frontend/**'
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v4
-
- - uses: actions/setup-node@v4
- with:
- node-version: 20
- cache: npm
- cache-dependency-path: frontend/package-lock.json
-
- - name: Install dependencies
- run: npm ci
- working-directory: frontend
-
- - name: Type check
- run: npx tsc --noEmit
- working-directory: frontend
-
- - name: Build
- run: npm run build
- working-directory: frontend
- env:
- GITHUB_PAGES: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8ab973e..340da36 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -74,12 +74,33 @@ jobs:
env:
GITHUB_PAGES: true
+ # ── VS Code extension ─────────────────────────────────────────────────────────
+ vscode-extension:
+ name: VS Code extension · type check & build
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: npm
+ cache-dependency-path: vscode-extension/package-lock.json
+ - name: Install dependencies
+ run: npm ci
+ working-directory: vscode-extension
+ - name: Compile
+ run: npm run compile
+ working-directory: vscode-extension
+
# ── PR scan (pull requests only) ──────────────────────────────────────────────
pr-scan:
name: KShield · scan changed files
runs-on: ubuntu-22.04
if: github.event_name == 'pull_request'
needs: [backend]
+ permissions:
+ contents: read
+ pull-requests: write
steps:
- uses: actions/checkout@v4
with:
@@ -99,7 +120,9 @@ jobs:
- name: Get changed files
run: |
git diff --name-only origin/${{ github.base_ref }}...HEAD \
- --diff-filter=ACM > /tmp/changed_files.txt
+ --diff-filter=ACM \
+ | grep -vE '(^|/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|Cargo\.lock)$' \
+ > /tmp/changed_files.txt || true
cat /tmp/changed_files.txt
- name: Scan changed files
id: scan
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 326ed2d..61006c4 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -121,8 +121,8 @@ jobs:
sed -i "s/version \".*\"/version \"${VERSION#v}\"/" homebrew/kshield.rb
sed -i "s/REPLACE_AFTER_LINUX_ARM64_BUILD/$LINUX_ARM_SHA/" homebrew/kshield.rb
sed -i "s/REPLACE_AFTER_LINUX_X86_BUILD/$LINUX_X86_SHA/" homebrew/kshield.rb
- [ -n "$ARM64_SHA" ] && sed -i "s/018ecd73ac71641382571f05cc10788dcf4f0319c1f132905ae3b00edef8935a/$ARM64_SHA/" homebrew/kshield.rb
- [ -n "$X86_SHA" ] && sed -i "s/81fcbd439887f6e2acbb2b6d9287f2d50eb5571ec386246f87c2755bbf1393cb/$X86_SHA/" homebrew/kshield.rb
+ sed -i "s/REPLACE_AFTER_MACOS_ARM64_BUILD/$ARM64_SHA/" homebrew/kshield.rb
+ sed -i "s/REPLACE_AFTER_MACOS_X86_BUILD/$X86_SHA/" homebrew/kshield.rb
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
@@ -169,3 +169,28 @@ jobs:
homebrew/kshield.rb
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
+
+ # ── Publish to PyPI ───────────────────────────────────────────────────────
+ publish-pypi:
+ name: Publish to PyPI
+ needs: [publish]
+ if: "!contains(github.ref_name, '-')"
+ runs-on: ubuntu-22.04
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+
+ - name: Build sdist and wheel
+ run: |
+ python -m pip install --upgrade build
+ python -m build
+
+ - name: Publish to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.kshield.yml b/.kshield.yml
new file mode 100644
index 0000000..59306f8
--- /dev/null
+++ b/.kshield.yml
@@ -0,0 +1,10 @@
+suppress:
+ paths:
+ - "package-lock.json"
+ - "**/package-lock.json"
+ - "yarn.lock"
+ - "**/yarn.lock"
+ - "pnpm-lock.yaml"
+ - "**/pnpm-lock.yaml"
+ - "Cargo.lock"
+ - "**/Cargo.lock"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba376d8..928a179 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,24 @@
All notable changes to KShield are documented here.
+## [Unreleased]
+
+### Added
+- `kshield-vscode` is now live on the VS Code Marketplace as [`YTTGlobal.kshield-vscode`](https://marketplace.visualstudio.com/items?itemName=YTTGlobal.kshield-vscode). Docs updated to lead with `code --install-extension YTTGlobal.kshield-vscode` ahead of the manual `.vsix` build steps.
+
+## [1.1.0] — 2026-07-17
+
+### Added
+- **VS Code extension** (`vscode-extension/`): inline security warnings as you type. Scans on file save (debounced), surfaces findings as editor diagnostics with hover explanations, and offers Quick Fix actions to apply remediation patches or suppress a rule globally. Talks to the same local backend the CLI manages.
+- **VS Code extension packaging**: `repository` field added to `vscode-extension/package.json` and a bundled `LICENSE` so `vsce package` produces a clean `.vsix` with no warnings — installable locally via `code --install-extension` or publishable to the Marketplace.
+- **Root `LICENSE` file** (MIT) added, matching the license already declared in `pyproject.toml` and `vscode-extension/package.json`.
+- **PyPI publishing**: release pipeline now builds and publishes the backend package to PyPI on every non-prerelease tag.
+
+### Fixed
+- All download routes (curl installer, npm installer, Homebrew formula, pip package URLs, CLI's own backend-download URL, VS Code extension repository link, in-app Docs page) pointed at the old GitHub org `YTTGlobalServices` and 404'd after the org moved to `YTT-Global`. Repointed everywhere, including two spots (`cli/src/setup.rs`, `frontend/src/components/Docs.tsx`) that a prior pass missed.
+- Homebrew formula's release-CI step was patching the wrong SHA-256 placeholder strings for macOS builds, leaving stale checksums in published formula updates.
+- `backend/requirements.txt` was missing `numpy`, despite `app/engine/model.py` importing it directly — added `numpy>=1.26` as an explicit dependency instead of relying on it being pulled in transitively by `tensorflow`.
+
## [1.0.0] — 2026-07-14
### Initial Release
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9c6884f..7588453 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -55,7 +55,7 @@ Follow [docs/setup.md](docs/setup.md) to get the full stack running locally.
Quick start:
```bash
-git clone https://github.com/YTTGlobalServices/kshield.git
+git clone https://github.com/YTT-Global/kshield.git
cd kshield
# Backend
@@ -69,6 +69,9 @@ cd ../frontend && npm install && npm run dev
# CLI (dev build)
cd ../cli && cargo build
./target/debug/kshield status
+
+# VS Code extension (dev build — press F5 in VS Code to launch it)
+cd ../vscode-extension && npm install && npm run compile
```
Or use the managed install for the backend:
@@ -107,6 +110,9 @@ All branches must fork from `main`.
# Frontend
cd frontend && npm run build && npm run lint
+
+ # VS Code extension
+ cd vscode-extension && npm run compile
```
4. Write a clear PR description:
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4a8a9ff
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 YTT Global
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 7a04bf0..eb7ff4c 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,9 @@
> The pre-commit security firewall for developers. Catches hardcoded secrets, broken access control, AI hallucinations, and supply-chain risks — entirely on your machine, before a single line reaches your remote.
-[](https://github.com/YTTGlobalServices/kshield/actions)
-[](https://github.com/YTTGlobalServices/kshield/releases/latest)
+[](https://github.com/YTT-Global/kshield/actions)
+[](https://github.com/YTT-Global/kshield/releases/latest)
+[](https://marketplace.visualstudio.com/items?itemName=YTTGlobal.kshield-vscode)
[](LICENSE)
[](#tech-stack)
@@ -21,7 +22,7 @@ Pick any one — they all end up at the same binary and the same experience:
**macOS / Linux (recommended):**
```bash
-curl -fsSL https://raw.githubusercontent.com/YTTGlobalServices/kshield/main/install.sh | bash
+curl -fsSL https://raw.githubusercontent.com/YTT-Global/kshield/main/install.sh | bash
```
**Homebrew (macOS):**
@@ -56,7 +57,7 @@ That's it. What happens:
```
✓ Git repository detected
✓ Pre-commit hook installed (.git/hooks/pre-commit)
-! Backend not installed — running setup (one-time)...
+! Backend not installed — running setup (one-time)…
✓ Python environment ready (~/.kshield/venv)
✓ Backend started (SQLite, no Docker needed)
✓ Ready. Make a commit to run your first scan.
@@ -66,7 +67,7 @@ Now make any commit — the firewall runs automatically:
```
KShield · Pre-Commit Scan
-Scanning 2 staged files...
+Scanning 2 staged files…
server.py ██ 2 issues
utils/auth.py ██ Clean
@@ -75,7 +76,7 @@ COMMIT BLOCKED · 2 issues found
CRITICAL server.py:12
Hardcoded Secret · GitHub Token detected
- api_key = 'ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+ api_key = 'ghp_'
↳ ELI5: Move this value to an environment variable → os.getenv('API_KEY')
HIGH server.py:28
@@ -145,11 +146,11 @@ Scans Python files for FastAPI route handlers (`sync` and `async`) with no authe
| Category | Examples |
|---|---|
-| Placeholder markers | `TODO: verify with production`, `insert logic here`, `not implemented yet` |
-| Credential stubs | `password = 'password'`, `api_key = 'fake'`, `disable auth` |
-| Hallucinated imports | `from internal_ai_test import`, `import mock_*`, `import fake_*` |
-| AI generation artifacts | `as an AI language model`, `replace this with your actual key`, `generated by Copilot` |
-| Dead code stubs | `raise NotImplementedError`, bare `...` function bodies |
+| Placeholder markers | `TODO: verify before prod`, `add logic in this spot`, `still needs implementing` |
+| Credential stubs | `password = 'hunter2'`, `api_key = 'stub-value'`, `bypass login checks` |
+| Hallucinated imports | `from internal_test_ai import`, `mock_-prefixed imports`, `fake_-prefixed imports` |
+| AI generation artifacts | `as an AI, I cannot`, `swap this stand-in for your real key`, `written by your AI pair programmer` |
+| Dead code stubs | `raise NotImplemented (stub)`, bare `...` function bodies |
Test files (`test_*.py`, `*_test.py`, files under `tests/`) are exempt — stubs are legitimate there.
@@ -232,10 +233,19 @@ kshield/
│ └── components/ # Badge · Button · Card · CodeBlock · Table
│ # Alert · StatusDot · PageHeader · Drawer
│ # EmptyState · Icons (SVG)
+├── vscode-extension/ # VS Code extension — inline warnings as you type
+│ └── src/
+│ ├── extension.ts # Activation, save watcher, command wiring
+│ ├── apiClient.ts # Backend HTTP client (/health, /api/v1/scan, /api/v1/suppress)
+│ ├── diagnostics.ts # Finding → vscode.Diagnostic mapping
+│ ├── hoverProvider.ts # ELI5 explanations on hover
+│ ├── codeActionProvider.ts # Quick Fix: apply patch / suppress rule
+│ └── patch.ts # Unified diff applier for remediation patches
├── npm/ # npx kshield wrapper package
├── homebrew/kshield.rb # Homebrew formula
├── install.sh # curl | bash installer
├── pyproject.toml # pip install kshield
+├── LICENSE # MIT
├── CHANGELOG.md
└── docs/
├── architecture.md
@@ -244,6 +254,28 @@ kshield/
---
+## VS Code Extension
+
+Inline diagnostics as you type — scans on save, shows squiggles with hover explanations, and offers Quick Fix actions to apply a patch or suppress a rule. Talks to the same local backend the CLI manages.
+
+**Install from the Marketplace (recommended):** search "KShield" in the Extensions view, or install directly:
+```bash
+code --install-extension YTTGlobal.kshield-vscode
+```
+Or via the [Marketplace listing](https://marketplace.visualstudio.com/items?itemName=YTTGlobal.kshield-vscode).
+
+**Build from source instead:**
+```bash
+cd vscode-extension
+npm install
+npx @vscode/vsce package
+code --install-extension kshield-vscode-.vsix --force
+```
+
+See [vscode-extension/README.md](vscode-extension/README.md) for settings and commands.
+
+---
+
## Managed Directory
After `kshield setup` or `kshield init`, the following is created in your home directory:
@@ -314,7 +346,7 @@ The backend exposes a REST API at `http://localhost:8000`. Full reference is ava
- [ ] Connect React dashboard to live backend endpoints
- [ ] Filter chips (CRITICAL / HIGH / MEDIUM) on anomaly list
- [ ] Toast notifications for patch application
-- [ ] VS Code extension — inline warnings as you type
+- [x] VS Code extension — inline warnings as you type
- [ ] Windows support
- [ ] Tauri desktop build packaging
diff --git a/SKILLS.md b/SKILLS.md
index d311911..5f33e05 100644
--- a/SKILLS.md
+++ b/SKILLS.md
@@ -136,7 +136,32 @@ This document is the authoritative system manual for AI development agents (Clau
---
-## 6. Integrity Invariants — Never Break These
+## 6. VS Code Extension (`/vscode-extension`)
+
+**Stack:** TypeScript · VS Code Extension API · `@vscode/vsce`
+
+### File Responsibilities
+
+| File | Owns |
+|---|---|
+| `src/extension.ts` | Activation, save-watcher wiring, command registration |
+| `src/apiClient.ts` | HTTP client for the local backend (`/health`, `/api/v1/scan`, `/api/v1/suppress`) |
+| `src/diagnostics.ts` | Maps backend findings to `vscode.Diagnostic` objects |
+| `src/hoverProvider.ts` | ELI5 explanation shown on hover over a squiggle |
+| `src/codeActionProvider.ts` | Quick Fix actions — apply patch / suppress rule |
+| `src/patch.ts` | Applies unified-diff `patch_diff` strings from remediation findings |
+| `src/statusBar.ts` | Backend reachability indicator |
+
+### Extension Rules
+
+- **The extension never bundles or starts the backend.** It only talks to it over HTTP at `kshield.backendUrl` (default `http://127.0.0.1:8000`). Do not add process-spawning logic here — that belongs to the CLI (`cli/src/setup.rs`).
+- **Packaging**: `package.json` must keep a valid `repository` field and the package must ship with a `LICENSE` file (copied from the repo root) — `vsce package` treats both as required for a warning-free `.vsix`. Do not remove either without also updating `.vscodeignore`.
+- **Auto-apply is patch-only**: only findings carrying a `patch_diff` (currently Broken Access Control) can go through `codeActionProvider.ts`'s apply-fix path. All other finding types must fall back to "Suppress This Rule" — do not fabricate a patch for finding types the backend doesn't provide one for.
+- **Changing the finding schema**: if `app/api/v1/scan.py`'s response model changes, update `src/types.ts` in lockstep (mirrors the same contract used by `frontend/src/types/scan.ts` and `cli/src/types.rs`).
+
+---
+
+## 7. Integrity Invariants — Never Break These
| # | Rule |
|---|---|
diff --git a/assets/linkedin-card.html b/assets/linkedin-card.html
new file mode 100644
index 0000000..5aa62b6
--- /dev/null
+++ b/assets/linkedin-card.html
@@ -0,0 +1,447 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Open Source
+
+ v1.0.0 · MIT License
+
+
+
+
The pre-commit security firewall for developers.
+
Stops vibe-coded vulnerabilities, hallucinated secrets, and broken auth from reaching your remote — entirely on your machine.