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
13 changes: 12 additions & 1 deletion hooks/fix-broken-links/link-fix.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ function Get-AgentAlts {
param([string]$Url,[int]$Max)
if (-not (Get-Command copilot -ErrorAction SilentlyContinue)) { return @() }
$snappy = $AGENT_TIMEOUT - 5
$prompt = "In under $snappy seconds, find up to $Max working alternative URLs for the broken link $Url. Hierarchically consider 1. Path and/or page spelling; 2. web.archive.org/wayback; 3. Redirects using redirect destination; 4. The context of the link's text; in order to resolve. Output only the URLs. One per line, and no: prose, numbering, markdown, backticks, special characters, post formatting."
$promptUrl = Get-PromptSafeUrl $Url
$prompt = "In under $snappy seconds, find up to $Max working alternative URLs for the broken link $promptUrl. Hierarchically consider 1. Path and/or page spelling; 2. web.archive.org/wayback; 3. Redirects using redirect destination; 4. The context of the link's text; in order to resolve. Output only the URLs. One per line, and no: prose, numbering, markdown, backticks, special characters, post formatting."
$out = ''
try {
# FIX_BROKEN_LINKS_AGENT marks the child run so a re-entrant hook exits early.
Expand Down Expand Up @@ -190,6 +191,16 @@ function Get-AgentAlts {
return ,$result.ToArray()
}

# Prepare a URL for safe embedding inside a prompt string.
# This is defense-in-depth for values that originate from document content.
function Get-PromptSafeUrl {
param([string]$Url)
if ($null -eq $Url) { return '' }
$safe = $Url -replace '[\r\n]+', ' '
$safe = $safe -replace '[`$()]', ''
return $safe
}

# Up to MAX viable replacement URLs for a broken link, best first:
# 1. a working scheme/www/slash variation (verified live 200)
# 2. alternatives proposed by the Copilot CLI agent (see Get-AgentAlts)
Expand Down
16 changes: 14 additions & 2 deletions hooks/fix-broken-links/link-fix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,10 @@ find_variation() {
# from anywhere in the output, trim trailing punctuation, drop the broken URL
# itself, and de-duplicate (case-insensitively). Up to MAX lines, one URL each.
agent_alts() {
local url="$1" max="$2" prompt out
local url="$1" max="$2" prompt out prompt_url
command -v copilot >/dev/null 2>&1 || return 0
prompt="In under $((AGENT_TIMEOUT - 5)) seconds, find up to ${max} working alternative URLs for the broken link ${url}. Hierarchically consider 1. Path and/or page spelling; 2. web.archive.org/wayback; 3. Redirects using redirect destination; 4. The context of the link's text; in order to resolve. Output only the URLs. One per line, and no: prose, numbering, markdown, backticks, special characters, post formatting."
prompt_url="$(sanitize_prompt_url "$url")"
prompt="In under $((AGENT_TIMEOUT - 5)) seconds, find up to ${max} working alternative URLs for the broken link ${prompt_url}. Hierarchically consider 1. Path and/or page spelling; 2. web.archive.org/wayback; 3. Redirects using redirect destination; 4. The context of the link's text; in order to resolve. Output only the URLs. One per line, and no: prose, numbering, markdown, backticks, special characters, post formatting."
# FIX_BROKEN_LINKS_AGENT marks the child run so a re-entrant hook exits early.
out="$(FIX_BROKEN_LINKS_AGENT=1 $AGENT_RUN copilot -p "$prompt" \
-s --no-color --model "$AGENT_MODEL" --available-tools 2>/dev/null)"
Expand Down Expand Up @@ -209,6 +210,17 @@ suggest_alts() {
printf '%s\n' "${out[@]}"
}

# Prepare a URL for safe embedding inside a shell-built prompt string.
# This is defense-in-depth for values that originate from document content.
sanitize_prompt_url() {
local s="$1"
s="${s//$'\r'/ }"
s="${s//$'\n'/ }"
s="${s//\`/\\\`}"
s="${s//\$/\\\$}"
printf '%s' "$s"
}

# Replace a literal URL everywhere in a file (pure bash, no regex).
replace_url() {
local file="$1" old="$2" new="$3" content pat
Expand Down
Loading