Skip to content
Back to skills

Nightgauge Docs Watch

ASecurity

Monitor Claude Code documentation for new features and changes relevant to the

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 5, 2026
ai-agentspythongobashgitdocumentation

Works with

  • claude code
  • cursor
  • cli
  • mcp

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro scans all 4 files and shows the line behind each finding

Scanned November 5, 2026

npx -y skills add nightgauge/nightgauge --skill nightgauge-docs-watch --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Nightgauge Docs Watch?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Nightgauge Docs Watch
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nightgauge-nightgauge-docs-watch/badge)](https://www.skillsdirectory.com/skills/nightgauge-nightgauge-docs-watch)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: nightgauge-docs-watch
description: Monitor Claude Code documentation for new features and changes relevant to the
  pipeline. Use when checking for Claude Code updates or when a new CC version is
  released.
license: Apache-2.0
metadata:
  author: nightgauge
  version: "1.0.0"
  source: https://github.com/nightgauge/nightgauge
allowed-tools: Bash Read Write Edit Glob Grep
---

# Nightgauge Docs Watch

## Description

Monitors Claude Code documentation at `https://code.claude.com/docs/` for new
pages, removed pages, and content changes. Compares the current state against a
locally stored snapshot and categorizes findings by relevance to the
Nightgauge pipeline.

**Use Cases:**

- Detecting new Claude Code features relevant to the pipeline
- Tracking documentation changes after a Claude Code release
- Auto-creating GitHub issues for high-relevance findings

**When to Use:**

- After a new Claude Code version is released
- On a periodic cadence (weekly or bi-weekly)
- When you suspect new features may be available

## Invocation

| Tool        | Command                                 |
| ----------- | --------------------------------------- |
| Claude Code | `/nightgauge:docs-watch [options]`      |
| Copilot     | Invoke via Agent Skills extension       |
| Cursor      | Run via Agent Skills or direct SKILL.md |
| Headless    | `claude -p "/nightgauge:docs-watch"`    |

## Arguments

| Argument                     | Description                                          | Default  |
| ---------------------------- | ---------------------------------------------------- | -------- |
| `--create-issues`            | Auto-create GitHub issues for high-relevance changes | `false`  |
| `--dry-run`                  | Show what issues would be created without creating   | `false`  |
| `--force-refresh`            | Re-fetch all pages, not just new/changed ones        | `false`  |
| `--correlate-releases`       | Cross-reference changes with Claude Code releases    | `true`\* |
| `--enrich-assessments`       | Update existing assessment files with doc links      | `false`  |
| `--skip-release-correlation` | Disable release correlation (e.g., for offline CI)   | `false`  |

\*Enabled by default when this checkout's `release-watch/last-seen-claude-code.json` exists
(`nightgauge layout path checkout release-watch/last-seen-claude-code.json`); disabled if missing.

### Examples

```bash
# Check for documentation changes (default: compare against last snapshot)
/nightgauge:docs-watch

# Check and auto-create issues for high-relevance changes
/nightgauge:docs-watch --create-issues

# Preview what issues would be created
/nightgauge:docs-watch --create-issues --dry-run

# Force re-fetch all pages and rebuild snapshot
/nightgauge:docs-watch --force-refresh

# Check changes and correlate with release versions
/nightgauge:docs-watch --correlate-releases

# Enrich existing assessment files with documentation context
/nightgauge:docs-watch --enrich-assessments
```

---

## Prerequisites

- `curl` installed (for fetching documentation pages)
- `sha256sum` or `shasum` installed (for content hashing)
- `jq` installed (for JSON processing)
- `gh` CLI installed and authenticated (only for `--create-issues`)
- Git repository with `.nightgauge/` directory

**CRITICAL**: This skill runs headless. Do NOT use AskUserQuestion. Make
autonomous decisions or fail with clear error.

---

## Workflow

### Phase 0: Environment Preflight

<!-- include: ../_shared/PREFLIGHT.md -->

---

### Phase 1: Fetch Current Documentation Index

#### Step 1.1: Fetch the docs index

Fetch the current page list from Claude Code documentation:

```bash
curl -s https://code.claude.com/docs/llms.txt > /tmp/docs-watch-index.txt
```

If the fetch fails, error with a clear message:

```bash
if [ ! -s /tmp/docs-watch-index.txt ]; then
  echo "ERROR: Failed to fetch docs index from https://code.claude.com/docs/llms.txt"
  echo "  Check network connectivity and try again."
  exit 1
fi
```

#### Step 1.2: Extract page URLs

Parse the index to extract all documentation page URLs. The `llms.txt` file
contains URLs (one per line or embedded in text). Extract all URLs matching
`https://code.claude.com/docs/`:

```bash
grep -oE 'https://code\.claude\.com/docs/[a-zA-Z0-9/_-]+' /tmp/docs-watch-index.txt \
  | sort -u > /tmp/docs-watch-urls.txt
PAGE_COUNT=$(wc -l < /tmp/docs-watch-urls.txt | tr -d ' ')
echo "Found ${PAGE_COUNT} documentation pages"
```

---

### Phase 2: Load Stored Snapshot

#### Step 2.1: Load or initialize snapshot

```bash
# This checkout's doc-snapshots/ inside the git directory (ADR-024 § 7):
# read by path, written only through `nightgauge layout write checkout`.
SNAPSHOT_NAME="doc-snapshots/index.json"
SNAPSHOT_FILE="$(nightgauge layout path checkout "$SNAPSHOT_NAME")"

if [ ! -f "$SNAPSHOT_FILE" ]; then
  echo '{"last_check":"1970-01-01T00:00:00Z","page_count":0,"pages":{}}' \
    | jq '.' | nightgauge layout write checkout "$SNAPSHOT_NAME" > /dev/null
  echo "Initialized new snapshot file at ${SNAPSHOT_FILE}"
fi
```

Read the snapshot into a temp file for comparison:

```bash
cp "$SNAPSHOT_FILE" /tmp/docs-watch-snapshot.json
LAST_CHECK=$(jq -r '.last_check' /tmp/docs-watch-snapshot.json)
echo "Last check: ${LAST_CHECK}"
```

---

### Phase 3: Compare Index Against Snapshot

#### Step 3.1: Detect new, existing, and removed pages

```bash
# Extract known URLs from snapshot
jq -r '.pages | keys[]' /tmp/docs-watch-snapshot.json | sort > /tmp/docs-watch-known.txt

# New pages: in current but not in snapshot
comm -23 /tmp/docs-watch-urls.txt /tmp/docs-watch-known.txt > /tmp/docs-watch-new.txt

# Removed pages: in snapshot but not in current
comm -13 /tmp/docs-watch-urls.txt /tmp/docs-watch-known.txt > /tmp/docs-watch-removed.txt

# Existing pages: in both
comm -12 /tmp/docs-watch-urls.txt /tmp/docs-watch-known.txt > /tmp/docs-watch-existing.txt

NEW_COUNT=$(wc -l < /tmp/docs-watch-new.txt | tr -d ' ')
REMOVED_COUNT=$(wc -l < /tmp/docs-watch-removed.txt | tr -d ' ')
EXISTING_COUNT=$(wc -l < /tmp/docs-watch-existing.txt | tr -d ' ')

echo "New pages: ${NEW_COUNT}"
echo "Removed pages: ${REMOVED_COUNT}"
echo "Existing pages to check: ${EXISTING_COUNT}"
```

---

### Phase 4: Fetch and Hash Content

Use the snapshot-diff script to detect content changes:

```bash
nightgauge docs snapshot-diff \
  --snapshot /tmp/docs-watch-snapshot.json \
  --urls /tmp/docs-watch-urls.txt \
  --json \
  > /tmp/docs-watch-diff.json
```

The script outputs JSON with `new`, `changed`, and `removed` arrays. Each entry
includes the URL and content hash.

If `--force-refresh` is set, treat ALL pages as new (ignore existing hashes).

---

### Phase 5: Categorize Findings by Relevance

Read the reference file for categorization criteria:

```bash
REFERENCE_FILE="${SKILL_DIR}/reference.md"
```

Apply relevance scoring based on page URL path segments. Use the categories
defined in `reference.md`:

**High relevance** (directly affects pipeline operation):

- sub-agents, skills, hooks, headless, mcp, plugins, permissions, settings,
  sdk, agent, automation, custom-commands

**Medium relevance** (useful for pipeline improvement):

- cli-reference, common-workflows, best-practices, tools-reference,
  github-actions, configuration, memory, context

**Low relevance** (informational only):

- authentication, data-usage, legal, troubleshooting, desktop, chrome, voice,
  pricing, changelog

For each new or changed page:

1. Fetch the page content: `curl -s <url>`
2. Generate sha256 hash of the content
3. Match URL path segments against relevance categories
4. Assign relevance: `high`, `medium`, or `low`
5. Extract a brief summary of the page content (first 200 chars or title)

---

### Phase 5.5: Release Correlation (Optional)

Only executes when `--skip-release-correlation` is not set AND this checkout's
`release-watch/last-seen-claude-code.json` exists.

#### Step 5.5.1: Load release state and recent reports

```bash
RELEASE_STATE_FILE="$(nightgauge layout path checkout release-watch/last-seen-claude-code.json)"
REPORTS_DIR="$(nightgauge layout path checkout release-watch/reports)"
export RELEASE_STATE_FILE REPORTS_DIR

if [ ! -f "$RELEASE_STATE_FILE" ]; then
  echo "Release state not found; skipping correlation"
  CORRELATE_RELEASES=false
else
  CURRENT_VERSION=$(jq -r '.version // .full_tag' "$RELEASE_STATE_FILE" 2>/dev/null | sed 's/^v//')
  CORRELATE_RELEASES=true
  echo "Will correlate changes with releases (current: ${CURRENT_VERSION})"
fi
```

#### Step 5.5.2: Correlate each detected change

For each new or changed page in the diff results, attempt correlation by:

1. **Timestamp matching** — If the change was detected within ±7 days of a release date,
   correlate with that release (confidence: high if exact match, medium if 3-7 days)
2. **URL pattern matching** — If the page URL contains version references (e.g.,
   `/docs/v2.1/...` or `/docs/2.1.81/...`), extract the version
3. **Content matching** — If the page content includes release notes or changelog,
   search for feature keywords from recent releases

```bash
python3 << 'PYTHON_EOF'
import json
import os
import re
from datetime import datetime, timedelta

def correlate_change(page_url, change_type, last_seen_iso, release_version, reports_dir):
    """Attempt to correlate a documentation change with a release.

    Returns:
    {
        'correlated_release': 'version string or null',
        'correlation_confidence': 'high|medium|low',
        'correlation_method': 'timestamp_match|url_pattern|content_match|none'
    }
    """
    result = {
        'correlated_release': None,
        'correlation_confidence': 'low',
        'correlation_method': 'none'
    }

    # Parse timestamps
    try:
        if last_seen_iso:
            change_date = datetime.fromisoformat(last_seen_iso.replace('Z', '+00:00'))
        else:
            return result
    except:
        return result

    # Method 1: URL pattern matching
    url_pattern = r'/(v?\d+\.\d+(?:\.\d+)?)[/]?'
    match = re.search(url_pattern, page_url)
    if match:
        version_from_url = match.group(1).lstrip('v')
        result['correlated_release'] = version_from_url
        result['correlation_confidence'] = 'medium'
        result['correlation_method'] = 'url_pattern'
        return result

    # Method 2: Timestamp matching (within ±7 days of release)
    # Load release reports to find nearest release date
    if os.path.isdir(reports_dir):
        try:
            reports = [f for f in os.listdir(reports_dir) if f.endswith('.json')]
            reports.sort(reverse=True)  # newest first

            for report_file in reports[:5]:  # check last 5 reports
                try:
                    with open(os.path.join(reports_dir, report_file)) as f:
                        report = json.load(f)

                    for release in report.get('releases', []):
                        release_date_str = release.get('published_at', '')
                        if not release_date_str:
                            continue

                        try:
                            release_date = datetime.fromisoformat(release_date_str.replace('Z', '+00:00'))
                            time_diff = abs((change_date - release_date).days)

                            if time_diff <= 1:  # exact day match
                                result['correlated_release'] = release['version']
                                result['correlation_confidence'] = 'high'
                                result['correlation_method'] = 'timestamp_match'
                                return result
                            elif time_diff <= 7:  # within 7 days
                                result['correlated_release'] = release['version']
                                result['correlation_confidence'] = 'medium'
                                result['correlation_method'] = 'timestamp_match'
                                # Don't return; keep looking for better match
                        except:
                            continue
                except:
                    continue
        except:
            pass

    return result

# Load current diff results
with open('/tmp/docs-watch-diff.json') as f:
    diff = json.load(f)

# Load release state
with open(os.environ['RELEASE_STATE_FILE']) as f:
    release_state = json.load(f)

current_version = release_state.get('version', release_state.get('full_tag', '')).lstrip('v')
reports_dir = os.environ['REPORTS_DIR']

# Enrich each change with correlation data
for entry_list in [diff.get('new', []), diff.get('changed', [])]:
    for entry in entry_list:
        correlation = correlate_change(
            entry['url'],
            'new' if entry in diff.get('new', []) else 'changed',
            entry.get('last_seen'),
            current_version,
            reports_dir
        )
        entry.update(correlation)

# Save enriched diff
with open('/tmp/docs-watch-diff-correlated.json', 'w') as f:
    json.dump(diff, f, indent=2)

print(f"Correlated {len(diff.get('new', [])) + len(diff.get('changed', []))} changes with releases")
PYTHON_EOF

# Use correlated diff for subsequent phases
cp /tmp/docs-watch-diff-correlated.json /tmp/docs-watch-diff.json
```

---

### Phase 6: Generate Report

#### Step 6.1: Build findings summary

```
CLAUDE CODE DOCS WATCH REPORT
═══════════════════════════════════════════════════════════
Check Date:    2026-03-19
Last Check:    2026-03-12
Pages Tracked: 72

CHANGES DETECTED
───────────────────────────────────────────────────────────
  New Pages:     3
  Changed Pages: 5
  Removed Pages: 0

HIGH RELEVANCE (action recommended)
───────────────────────────────────────────────────────────
  [NEW] https://code.claude.com/docs/sub-agents
    → New sub-agent capabilities may affect pipeline stage isolation

  [CHANGED] https://code.claude.com/docs/hooks
    → Content hash changed — review for new hook types

MEDIUM RELEVANCE (review recommended)
───────────────────────────────────────────────────────────
  [CHANGED] https://code.claude.com/docs/cli-reference
    → CLI flags may have new options for headless execution

LOW RELEVANCE (informational)
───────────────────────────────────────────────────────────
  [NEW] https://code.claude.com/docs/troubleshooting-faq
    → New troubleshooting page added

───────────────────────────────────────────────────────────
Run with --create-issues to auto-create GitHub issues for high-relevance findings.
```

#### Step 6.2: Write JSON report

Write structured results to `/tmp/docs-watch-report.json`:

```json
{
  "check_date": "ISO-8601",
  "last_check": "ISO-8601",
  "page_count": 72,
  "new_pages": [],
  "changed_pages": [],
  "removed_pages": [],
  "findings": [
    {
      "url": "https://code.claude.com/docs/sub-agents",
      "type": "new",
      "relevance": "high",
      "summary": "Brief description of the page content",
      "correlated_release": "2.1.81",
      "correlation_confidence": "high",
      "correlation_method": "timestamp_match"
    }
  ],
  "release_correlation": {
    "enabled": true,
    "current_release": "2.1.81",
    "correlated_count": 3,
    "high_confidence_count": 1,
    "medium_confidence_count": 1,
    "low_confidence_count": 1
  }
}
```

---

### Phase 7: Update Snapshot

Write the updated snapshot with current hashes:

```bash
# Build updated snapshot from diff results
python3 -c "
import json, sys
from datetime import datetime

# Load existing snapshot
with open('/tmp/docs-watch-snapshot.json') as f:
    snapshot = json.load(f)

# Load diff results
with open('/tmp/docs-watch-diff.json') as f:
    diff = json.load(f)

# Update pages with new/changed hashes and correlation data
for entry in diff.get('new', []) + diff.get('changed', []):
    page_data = {
        'hash': entry['hash'],
        'last_seen': datetime.utcnow().isoformat() + 'Z',
        'relevance': entry.get('relevance', 'low')
    }

    # Add correlation data if present (optional, for backward compatibility)
    if entry.get('correlated_release'):
        page_data['correlated_release'] = entry.get('correlated_release')
        page_data['correlation_confidence'] = entry.get('correlation_confidence', 'low')
        page_data['correlation_method'] = entry.get('correlation_method', 'none')

    snapshot['pages'][entry['url']] = page_data

# Remove deleted pages
for entry in diff.get('removed', []):
    snapshot['pages'].pop(entry['url'], None)

# Update metadata
snapshot['last_check'] = datetime.utcnow().isoformat() + 'Z'
snapshot['page_count'] = len(snapshot['pages'])

with open('/tmp/docs-watch-snapshot-updated.json', 'w') as f:
    json.dump(snapshot, f, indent=2)

print(f'Snapshot updated: {len(snapshot[\"pages\"])} pages tracked')
"
nightgauge layout write checkout "$SNAPSHOT_NAME" \
  --from /tmp/docs-watch-snapshot-updated.json > /dev/null
```

---

### Phase 8: Issue Creation (Optional)

Only executes when `--create-issues` is passed and `--dry-run` is false.

#### Step 8.1: Filter high-relevance findings

Only create issues for findings with `relevance: high`.

#### Step 8.2: Check for existing issues

```bash
gh issue list --search "claude-code-feature" --label "claude-code-feature" \
  --state open --json number,title
```

Skip creation if a matching issue already exists.

#### Step 8.3: Create issues

For each high-relevance finding:

```bash
gh issue create \
  --title "feat: Claude Code doc change — ${PAGE_NAME}" \
  --body "$(cat <<EOF
## Summary

A ${CHANGE_TYPE} was detected in Claude Code documentation that may affect the
Nightgauge pipeline.

**Page:** ${URL}
**Change Type:** ${CHANGE_TYPE}
**Relevance:** High
$(if [ -n "${CORRELATED_RELEASE}" ]; then echo "**Correlated Release:** v${CORRELATED_RELEASE} (${CORRELATION_CONFIDENCE} confidence)"; fi)

## Details

${SUMMARY}

## Action Items

- [ ] Review the documentation change
- [ ] Assess impact on pipeline stages
- [ ] Implement any necessary updates

## Release Correlation

This change was correlated with release v${CORRELATED_RELEASE} using ${CORRELATION_METHOD}.
See \`docs-watch\` Release Correlation feature in
[skills/nightgauge-docs-watch/correlation-reference.md](../../skills/nightgauge-docs-watch/correlation-reference.md)
for details on how correlation works and confidence scoring.

## Source

Auto-detected by \`/nightgauge:docs-watch\` on $(date -u +%Y-%m-%dT%H:%M:%SZ)
EOF
)" \
  --label "claude-code-feature,auto-detected"
```

For `--dry-run`, output what would be created without actually creating.

#### Step 8.4: Report created issues

Output list of created issues with numbers, titles, and URLs.

---

### Phase 9: Run Reflection

The snapshot (`index.json`) already tracks per-page state; this log tracks the
**per-run delta** so each run can report "since last check" at a glance.

```bash
SKILL_NAME="nightgauge-docs-watch"
RUN_LOG_CLASS="checkout"
RUN_LOG_NAME="doc-snapshots/runs.jsonl"
RUN_LOG="$(nightgauge layout path "$RUN_LOG_CLASS" "$RUN_LOG_NAME")"
```

<!-- include: ../_shared/RUN_REFLECTION.md -->

Set `RUN_COUNTS` (e.g. `{"new":N,"changed":N,"removed":N,"issues_created":N}`)
and `RUN_SUMMARY` from the Phase 6 report before the append step.

---

### Self-Assessment Epilogue

<!-- include: ../_shared/SELF_ASSESSMENT_EPILOGUE.md -->

---

## Error Handling

| Condition                             | Action                                   |
| ------------------------------------- | ---------------------------------------- |
| Network failure fetching docs index   | Error with connectivity instructions     |
| curl timeout on individual page       | Skip page, note in report                |
| Malformed snapshot JSON               | Re-initialize snapshot, warn user        |
| `gh` CLI not authenticated            | Error with `gh auth login` instructions  |
| `--create-issues` with no findings    | Output "No high-relevance changes found" |
| `--dry-run` without `--create-issues` | Warn, continue with analysis only        |
| sha256sum/shasum not found            | Try both, error if neither available     |
| jq not installed                      | Error with install instructions          |

---

## Pipeline Position

```
UTILITIES (not part of main pipeline)

/nightgauge:docs-watch
       ↑
  Use on regular cadence or after CC releases
  Reads:  https://code.claude.com/docs/llms.txt
  Reads:  checkout doc-snapshots/index.json
  Writes: checkout doc-snapshots/index.json
  Writes: /tmp/docs-watch-report.json (ephemeral)
```

This is a standalone utility skill. It does not affect pipeline state and can be
run at any time without interfering with active pipeline runs.

---

**Author:** nightgauge **License:** Apache-2.0

Files in this skill

  • SKILL.md21 KB
  • correlation-reference.md12.4 KB
  • reference.md9.1 KB
  • scripts/snapshot-diff.sh3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.