From efac8a7997d747f3be8493050ff47a445106492b Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 24 Jun 2026 19:32:05 +0000 Subject: [PATCH 1/5] chore(config.yaml): bump SkillSpector pin to enable real Claude LLM mode The previous pin (2eb84478) used langchain_openai.ChatOpenAI against Anthropic's /v1/chat/completions compat endpoint, which rejects the JSON Schema 'minimum'/'maximum' keywords SkillSpector's analyzer nodes emit on integer and number fields (start_line: ge=1, confidence: ge=0.0 le=1.0). Every semantic_* analyzer + the meta_analyzer returned HTTP 400, fell back to static-only, and shipped 23 raw findings on coder/setup that should have been filtered. Upstream fixed this in 7bc9c0fe by rewriting the anthropic provider to use langchain_anthropic.ChatAnthropic against /v1/messages, which accepts those keywords. Verified end-to-end in the workspace: install pulls langchain_anthropic 1.4.7, ChatAnthropic builds, with_structured_output on the exact Pydantic schema SkillSpector uses round-trips a real Claude call. --- config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index 18a9019..836daba 100644 --- a/config.yaml +++ b/config.yaml @@ -33,7 +33,7 @@ scanners: # the version in two places. Dependabot does not parse this file, # so a bumper bot lives outside the loop until the upstream # publishes to PyPI and the pin can move into pyproject.toml. - pin: "skillspector @ git+https://github.com/NVIDIA/SkillSpector.git@2eb844780ab163f01468ecf142c40a2ec0fcaec0" + pin: "skillspector @ git+https://github.com/NVIDIA/SkillSpector.git@7bc9c0feb663375ced6e7436008d082e6e3486ea" # Empty so .github/workflows/scan.yaml can append --no-llm # dynamically based on whether the LLM credential secret is set. flags: [] From 1b2dad5e104a19f8a1de1317d8a57ab897692288 Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 24 Jun 2026 19:32:05 +0000 Subject: [PATCH 2/5] fix(site): set Vite base path so Pages SPA loads under /coder-skill-scanner/ GitHub Pages serves project sites at //, but the Vite build was emitting absolute asset paths (/assets/index-...js, /favicon.svg) that resolved to the apex of github.io and 404'd. Result: HTML loaded, script tag 404'd, nothing rendered. Three coordinated changes: - vite.config.ts: base = '/coder-skill-scanner/' on build, '/' on dev. - src/router.tsx: createBrowserRouter basename = import.meta.env.BASE_URL so SPA routes resolve under the same prefix. - index.html + Layout.tsx + api.ts + History/Overview pages: replace the remaining hardcoded leading-slash references to latest.json, schema.json, history, favicon.svg, and logo.png with %BASE_URL% (HTML) or import.meta.env.BASE_URL (TSX). Verified by running 'pnpm build' locally: every asset reference in the emitted dist/ now starts with /coder-skill-scanner/. --- site/index.html | 4 ++-- site/src/components/Layout/Layout.tsx | 12 ++++++------ site/src/lib/api.ts | 4 +++- site/src/pages/HistoryPage.tsx | 5 ++++- site/src/pages/OverviewPage.tsx | 5 ++++- site/src/router.tsx | 3 +++ site/vite.config.ts | 6 +++++- 7 files changed, 27 insertions(+), 12 deletions(-) diff --git a/site/index.html b/site/index.html index af0248f..0b7b6d4 100644 --- a/site/index.html +++ b/site/index.html @@ -18,14 +18,14 @@ /> - +
diff --git a/site/src/components/Layout/Layout.tsx b/site/src/components/Layout/Layout.tsx index 7c33681..6be93df 100644 --- a/site/src/components/Layout/Layout.tsx +++ b/site/src/components/Layout/Layout.tsx @@ -22,16 +22,16 @@ type UtilityLink = { }; const utilityNav: UtilityLink[] = [ - { href: "/latest.json", label: "Raw JSON" }, - { href: "/schema.json", label: "Schema" }, + { href: `${import.meta.env.BASE_URL}latest.json`, label: "Raw JSON" }, + { href: `${import.meta.env.BASE_URL}schema.json`, label: "Schema" }, { href: "https://github.com/coder/coder-skill-scanner", label: "GitHub", external: true }, { href: "https://registry.coder.com", label: "Registry", external: true }, ]; const footerLinks: UtilityLink[] = [ - { href: "/latest.json", label: "Raw JSON" }, - { href: "/schema.json", label: "Schema (v1)" }, - { href: "/history", label: "History" }, + { href: `${import.meta.env.BASE_URL}latest.json`, label: "Raw JSON" }, + { href: `${import.meta.env.BASE_URL}schema.json`, label: "Schema (v1)" }, + { href: `${import.meta.env.BASE_URL}history`, label: "History" }, { href: "https://github.com/coder/coder-skill-scanner", label: "Source", external: true }, { href: "https://github.com/coder/coder-skill-scanner/blob/main/LICENSE", @@ -62,7 +62,7 @@ export const Layout: FC = () => { aria-label="Coder Skill Scanner home" > Coder Skill Scanner(path: string, signal?: AbortSignal): Promise { - const url = path.startsWith("/") ? path : `/${path}`; + const url = path.startsWith("/") + ? path + : `${import.meta.env.BASE_URL}${path}`; const res = await fetch(url, { cache: "no-cache", signal }); if (!res.ok) { throw new Error(`HTTP ${res.status} fetching ${path}`); diff --git a/site/src/pages/HistoryPage.tsx b/site/src/pages/HistoryPage.tsx index 3dfe2c8..55ffade 100644 --- a/site/src/pages/HistoryPage.tsx +++ b/site/src/pages/HistoryPage.tsx @@ -18,7 +18,10 @@ export const HistoryPage: FC = () => {
History begins populating after the first scheduled scan. The latest snapshot is always available as the{" "} - + raw JSON report . diff --git a/site/src/pages/OverviewPage.tsx b/site/src/pages/OverviewPage.tsx index 869e337..09854c6 100644 --- a/site/src/pages/OverviewPage.tsx +++ b/site/src/pages/OverviewPage.tsx @@ -34,7 +34,10 @@ export const OverviewPage: FC = () => {
Try fetching the{" "} - + raw JSON report {" "} directly. diff --git a/site/src/router.tsx b/site/src/router.tsx index 22cbc8d..12f3c92 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -20,4 +20,7 @@ export const router = createBrowserRouter( } /> , ), + // basename mirrors Vite's `base` config so SPA routes resolve correctly + // when the site is served under a project-page prefix (e.g. /coder-skill-scanner/). + { basename: import.meta.env.BASE_URL }, ); diff --git a/site/vite.config.ts b/site/vite.config.ts index d7eb2c3..1ca1670 100644 --- a/site/vite.config.ts +++ b/site/vite.config.ts @@ -14,11 +14,15 @@ import react from "@vitejs/plugin-react-swc"; */ const REPORT_REGEX = /^\/(latest\.json|schema\.json|history\/.+\.json)$/; -export default defineConfig(({ mode }) => { +export default defineConfig(({ mode, command }) => { const env = loadEnv(mode, process.cwd(), ""); const upstream = env.VITE_REPORT_UPSTREAM || "http://localhost:8765"; return { + // GitHub Pages serves this site at /coder-skill-scanner/. Production + // builds emit asset URLs relative to that base. Dev keeps the default + // `/` so the local Vite server and its report proxy keep working. + base: command === "build" ? "/coder-skill-scanner/" : "/", plugins: [react()], server: { host: "0.0.0.0", From 7a7ba0578c292c9eb6c85b55a03031fefd9fb2c6 Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 24 Jun 2026 19:32:05 +0000 Subject: [PATCH 3/5] chore(scan.yaml): bump deprecated download-artifact and deploy-pages GitHub annotated every scan run with 'Node.js 20 is deprecated' because actions/download-artifact@v5.0.0 and actions/deploy-pages@v4.0.5 still target Node 20. Bump to v8.0.1 and v5.0.0 (both Node 24). --- .github/workflows/scan.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scan.yaml b/.github/workflows/scan.yaml index 3dd6acb..9b51bc2 100644 --- a/.github/workflows/scan.yaml +++ b/.github/workflows/scan.yaml @@ -166,7 +166,7 @@ jobs: python -m pip install --upgrade pip pip install -e . - name: Download all skill artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: scans pattern: skill-* @@ -194,12 +194,12 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Download scan-index - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: scan-index path: . - name: Download all skill artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: skills pattern: skill-* @@ -282,7 +282,7 @@ jobs: python -m pip install --upgrade pip pip install -e . - name: Download scan-index - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: scan-index path: . @@ -328,7 +328,7 @@ jobs: path: pages - name: Deploy Pages id: deploy - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 open-issue-on-failure: name: Open or update tracker issue From a401700566742e14aa9d5ea7cfbc273ff6c3d7a8 Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 24 Jun 2026 19:42:21 +0000 Subject: [PATCH 4/5] chore(workflows): full pin audit, bump everything to latest Audited every action SHA, version tag comment, and toolchain pin across both workflow files plus mise.toml. Found a mix of real out-of-date pins and stale comment mismatches: actions/setup-python: SHA bump v6.2.0 -> v6.3.0 actions/setup-node: comment-only was tagged v6.0.0, SHA is v6.4.0 actions/upload-artifact: comment-only x2 was tagged v5.1.0, SHA is v7.0.1 mikefarah/yq: SHA bump v4.44.6 -> v4.53.3 pnpm: 10.33.2 -> 10.34.4 (mise + both workflows) node-version: '20' -> '22' in the markdownlint job (was the only Node 20 holdout; everything else was 22) Untouched because already current: actions/checkout v7.0.0 actions/download-artifact v8.0.1 (PR #11) actions/deploy-pages v5.0.0 (PR #11) actions/upload-pages-artifact v5.0.0 pnpm/action-setup v6.0.9 --- .github/workflows/ci.yaml | 14 +++++++------- .github/workflows/scan.yaml | 16 ++++++++-------- mise.toml | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d99a130..3b85d16 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up yq - uses: mikefarah/yq@b534aa9ee5d38001fba3cd8fe254a037e4847b37 # v4.44.6 + uses: mikefarah/yq@1b9b4ac5187171d2e5e3129be0cfa827c7f9d53d # v4.53.3 - name: Parse YAML run: yq eval . config.yaml > /dev/null - name: Required keys present @@ -57,7 +57,7 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install check-jsonschema @@ -76,7 +76,7 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install @@ -97,9 +97,9 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Node - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.0.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: - node-version: "20" + node-version: "22" - name: Run markdownlint-cli2 run: npx --yes markdownlint-cli2@0.18.1 "**/*.md" "!**/node_modules/**" "!LICENSE" @@ -117,9 +117,9 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: - version: 10.33.2 + version: 10.34.4 - name: Set up Node - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.0.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: "22" cache: "pnpm" diff --git a/.github/workflows/scan.yaml b/.github/workflows/scan.yaml index 9b51bc2..f0ebf3d 100644 --- a/.github/workflows/scan.yaml +++ b/.github/workflows/scan.yaml @@ -31,7 +31,7 @@ jobs: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install @@ -56,7 +56,7 @@ jobs: - name: Checkout scanner uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install scanner @@ -141,7 +141,7 @@ jobs: --skillspector-json out/skillspector.json \ --output out/skill.json - name: Upload skill artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5.1.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: skill-${{ matrix.namespace }}-${{ matrix.slug }} path: out/ @@ -158,7 +158,7 @@ jobs: - name: Checkout scanner uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install @@ -178,7 +178,7 @@ jobs: run: | python -c "import json; r=json.load(open('latest.json')); print(json.dumps(r['summary'], indent=2))" - name: Upload scan-index artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v5.1.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: scan-index path: latest.json @@ -266,15 +266,15 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 with: - version: 10.33.2 + version: 10.34.4 - name: Set up Node - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.0.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: "22" cache: "pnpm" cache-dependency-path: site/pnpm-lock.yaml - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "3.12" - name: Install scanner diff --git a/mise.toml b/mise.toml index e7796b8..3358128 100644 --- a/mise.toml +++ b/mise.toml @@ -2,4 +2,4 @@ [tools] python = "3.12" node = "22" -pnpm = "10.33.2" +pnpm = "10.34.4" From 2baf2b757b07840caf5496235cae23068f805a71 Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 24 Jun 2026 19:47:20 +0000 Subject: [PATCH 5/5] fix(site): derive base from GITHUB_REPOSITORY and fix 404 redirect target Addresses Copilot review feedback on PR #11. vite.config.ts: Production `base` is no longer hardcoded to /coder-skill-scanner/. Resolves via: 1. VITE_BASE_PATH env (explicit override) 2. GITHUB_REPOSITORY (CI default; forks Just Work with zero config) 3. / (apex / local-build fallback) Dev keeps / so the local Vite server and report proxy work without env juggling. public/404.html + new rewrite-public-base-url Vite plugin: The GitHub Pages SPA-fallback page redirected to /?p=... (apex), which bounced users off the project page and onto the github.io apex instead of bringing them back into the SPA. Use %BASE_URL% as the redirect prefix and substitute it at build time via a tiny plugin (Vite handles the substitution for index.html but copies public/ verbatim). Verified with four build runs (GITHUB_REPOSITORY=coder/coder-skill-scanner, GITHUB_REPOSITORY=someone-else/my-scanner, VITE_BASE_PATH override, no env). In every case the bases emitted in dist/index.html and the target string in dist/404.html match. --- site/public/404.html | 11 +++++--- site/vite.config.ts | 60 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/site/public/404.html b/site/public/404.html index dc1ce7b..c1bc6e4 100644 --- a/site/public/404.html +++ b/site/public/404.html @@ -5,9 +5,14 @@ Coder Skill Scanner