From 3e96fab7022b91d03b62a8d4368b8cd38077e916 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 01:00:37 +0000 Subject: [PATCH] chore: publish from staged --- .codespellrc | 4 +- docs/README.hooks.md | 1 + hooks/fix-broken-links/README.md | 177 ++++++++++++ hooks/fix-broken-links/hooks.json | 14 + hooks/fix-broken-links/link-fix.ps1 | 410 ++++++++++++++++++++++++++++ hooks/fix-broken-links/link-fix.sh | 372 +++++++++++++++++++++++++ 6 files changed, 977 insertions(+), 1 deletion(-) create mode 100644 hooks/fix-broken-links/README.md create mode 100644 hooks/fix-broken-links/hooks.json create mode 100644 hooks/fix-broken-links/link-fix.ps1 create mode 100644 hooks/fix-broken-links/link-fix.sh diff --git a/.codespellrc b/.codespellrc index e9272550..c554845f 100644 --- a/.codespellrc +++ b/.codespellrc @@ -54,7 +54,9 @@ # CAF - Microsoft Cloud Adoption Framework acronym -ignore-words-list = numer,wit,aks,edn,ser,ois,gir,rouge,categor,aline,ative,afterall,deques,dateA,dateB,TE,FillIn,alle,vai,LOD,InOut,pixelX,aNULL,Wee,Sherif,queston,Vertexes,nin,FO,CAF,Parth +# ans - bash and powershell variable short for answer + +ignore-words-list = numer,wit,aks,edn,ser,ois,gir,rouge,categor,aline,ative,afterall,deques,dateA,dateB,TE,FillIn,alle,vai,LOD,InOut,pixelX,aNULL,Wee,Sherif,queston,Vertexes,nin,FO,CAF,Parth,ans # Skip certain files and directories diff --git a/docs/README.hooks.md b/docs/README.hooks.md index f0682632..ba3f4d44 100644 --- a/docs/README.hooks.md +++ b/docs/README.hooks.md @@ -32,6 +32,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-hooks) for guidelines on how to | Name | Description | Events | Bundled Assets | | ---- | ----------- | ------ | -------------- | | [Dependency License Checker](../hooks/dependency-license-checker/README.md) | Scans newly added dependencies for license compliance (GPL, AGPL, etc.) at session end | sessionEnd | `check-licenses.sh`
`hooks.json` | +| [Fix Broken Links](../hooks/fix-broken-links/README.md) | Checks changed web files for broken hyperlinks and SEO anchor issues after each Copilot tool use. | postToolUse | `hooks.json`
`link-fix.ps1`
`link-fix.sh` | | [Governance Audit](../hooks/governance-audit/README.md) | Scans Copilot agent prompts for threat signals and logs governance events | sessionStart, sessionEnd, userPromptSubmitted | `audit-prompt.sh`
`audit-session-end.sh`
`audit-session-start.sh`
`hooks.json` | | [Secrets Scanner](../hooks/secrets-scanner/README.md) | Scans files modified during a Copilot coding agent session for leaked secrets, credentials, and sensitive data | sessionEnd | `hooks.json`
`scan-secrets.sh` | | [Session Auto-Commit](../hooks/session-auto-commit/README.md) | Automatically commits and pushes changes when a Copilot coding agent session ends | sessionEnd | `auto-commit.sh`
`hooks.json` | diff --git a/hooks/fix-broken-links/README.md b/hooks/fix-broken-links/README.md new file mode 100644 index 00000000..5adbaafd --- /dev/null +++ b/hooks/fix-broken-links/README.md @@ -0,0 +1,177 @@ +--- +name: 'Fix Broken Links' +description: 'Checks changed web files for broken hyperlinks and SEO anchor issues after each Copilot tool use.' +tags: ['links', 'seo', 'html', 'markdown', 'post-tool-use'] +--- + +# Fix Broken Links Hook + +Scans recently-changed web files for broken hyperlinks after each GitHub Copilot +tool use. For each broken URL the hook tries common spelling variations, then hands +the link to the Copilot CLI agent for suggested replacements, and presents an +interactive fix menu. Generic anchor text (`click here`, `read more`, etc.) is +flagged as an SEO issue. + +## Overview + +Broken links accumulate silently in web projects. Running on the `postToolUse` +event, this hook checks the web files the agent just edited — and only those — +right after each change, so you can fix, replace, or remove each broken link in +the same terminal session. + +The hook has two modes: + +- **With file paths** (the edited files injected from the hook payload, or paths + passed on the command line): it checks each link, looks up replacement + candidates, and presents the interactive fix menu. +- **With no file arguments**: it simply lists the broken links it finds — no + replacement lookups and no prompts. + +## Features + +- **Self-contained core**: bash and PowerShell ports — no runtime to install (the optional agent + hand-off reuses the Copilot CLI you already have) +- **Edited-files scope**: as a `postToolUse` hook it only checks the files the agent just changed — + never a full repo scan +- **Format-agnostic link scan**: extracts every `http(s)` URL with `grep`, covering HTML, Markdown, + JS/TS, JSON, CSS, SQL, and templates at once +- **Automatic URL healing**: tries www, https, and trailing-slash variations +- **Agent-assisted suggestions**: hands the broken link to the Copilot CLI agent (a lightweight, + low-token `gpt-5-mini` prompt with no tools) for replacement candidates; if the CLI is missing or + errors, it simply offers none +- **SEO audit**: flags anchor text that is too generic to benefit search ranking +- **Large-file guard**: prompts before checking files with more than 50 links +- **Interactive fix menu**: replace with suggestion, enter custom URL, strip tag keeping text, or + skip +- **Standard tools only**: `curl`, `grep`, `sed` — present on any POSIX system + +## Installation + +1. Copy the hook folder to your repository: + + ```bash + cp -r hooks/fix-broken-links .github/hooks/ + ``` + +2. Make the script executable: + + ```bash + chmod +x .github/hooks/fix-broken-links/link-fix.sh + ``` + +3. Commit the hook configuration to your repository's default branch. + +## Configuration + +The hook is configured in `hooks.json` to run on the `postToolUse` event: + +```json +{ + "version": 1, + "hooks": { + "postToolUse": [ + { + "type": "command", + "bash": ".github/hooks/fix-broken-links/link-fix.sh", + "powershell": ".github/hooks/fix-broken-links/link-fix.ps1", + "cwd": ".", + "timeoutSec": 120 + } + ] + } +} +``` + +## Supported Source Types + +Links are found by scanning each file for `http(s)://` URLs, so the same logic +covers every format that embeds absolute URLs: + +| Source | Examples matched | +| --- | --- | +| HTML | ``, ``, `