---
name: kodadocs-docs-refresh
description: "Incrementally regenerate documentation by detecting code changes, mapping them to affected routes, and updating only what changed."
---

# Docs Refresh (Incremental Regeneration)

## Overview

This skill performs an incremental documentation update by analyzing recent code changes, identifying which routes and pages are affected, and regenerating only the documentation that needs updating. Instead of rebuilding the entire doc site from scratch, it preserves unchanged articles and manual edits, re-captures only the affected screenshots, and re-generates only the affected articles.

Use this skill when:
- You have pushed code changes and want the docs to reflect them
- You want faster doc regeneration without a full pipeline run
- You have manually edited some articles and want to preserve those edits
- You are iterating on a feature and want to see updated docs quickly
- A CI pipeline triggers docs refresh on each merge to main

## Prerequisites

Before running this skill, ensure the following:

1. **Existing doc site:** A KodaDocs doc site must have been generated at least once. The manifest file `.kodadocs/run_manifest.json` must exist.
2. **Git repository:** The project must be a git repository with recent commit history.
3. **Application running (for screenshots):** If screenshots need to be re-captured, the application should be running at an accessible URL.
4. **KodaDocs MCP tools available:** The `mcp__kodadocs__*` tools must be accessible.

## Workflow

### Step 1: Determine the Change Window

Identify which files have changed since the last documentation generation.

**Approach A: Git diff from last run**

Load the manifest to find when docs were last generated:
```
Call mcp__kodadocs__load_manifest with:
  project_path: "<project-root>"
```

Extract the `last_run_timestamp` or `last_commit_sha` from the manifest. If a commit SHA is stored:
```bash
git diff --name-only <last_commit_sha>..HEAD
```

If only a timestamp is stored:
```bash
git diff --name-only --since="<timestamp>" HEAD
```

**Approach B: Explicit commit range**

If the user specifies a range (e.g., "last 3 commits"):
```bash
git diff --name-only HEAD~3..HEAD
```

Or a specific branch comparison:
```bash
git diff --name-only main..feature-branch
```

**Approach C: Working directory changes**

If the user wants to preview uncommitted changes:
```bash
git diff --name-only HEAD
git diff --name-only --staged
```

Combine both outputs and deduplicate.

**Store the changed file list** for use in subsequent steps. Also capture the current HEAD commit SHA:
```bash
git rev-parse HEAD
```

### Step 2: Classify Changed Files

Categorize each changed file to determine its documentation impact.

**File classification table:**

| File Pattern | Impact | Action |
|-------------|--------|--------|
| `pages/**`, `app/**`, `src/routes/**` | Route content changed | Re-capture screenshot, re-generate article |
| `components/**`, `src/components/**` | UI component changed | Re-capture screenshots for routes that use this component |
| `lib/**`, `utils/**`, `helpers/**` | Utility code changed | Re-generate articles that reference these utilities |
| `styles/**`, `css/**`, `*.css`, `*.scss` | Visual change only | Re-capture all screenshots (styles are global) |
| `public/**`, `static/**`, `assets/**` | Static assets changed | Re-capture screenshots (images/icons may appear in UI) |
| `package.json`, `requirements.txt` | Dependencies changed | Check if new routes or features were added |
| `*.config.*`, `.env*` | Configuration changed | May affect routing or feature flags |
| `README.md`, `docs/**/*.md` | Documentation source changed | No action (these are inputs, not app code) |
| `tests/**`, `__tests__/**`, `*.test.*` | Test files | No documentation impact -- skip |
| `.github/**`, `.gitlab-ci.yml` | CI configuration | No documentation impact -- skip |

**Build the affected file list** by filtering out files with no documentation impact (tests, CI configs, docs source).

### Step 3: Map Changed Files to Affected Routes

Determine which routes are affected by the changed files. This mapping is framework-specific.

**Call route discovery for current state:**
```
Call mcp__kodadocs__discover_routes with:
  project_path: "<project-root>"
```

**Next.js (App Router):**
- Files in `app/` map directly to routes: `app/dashboard/page.tsx` -> `/dashboard`
- Layout files (`layout.tsx`) affect all child routes in that directory
- `app/api/**` routes are API endpoints -- skip unless they power visible UI

**Next.js (Pages Router):**
- Files in `pages/` map directly: `pages/settings.tsx` -> `/settings`
- `pages/_app.tsx` or `pages/_document.tsx` affect ALL routes
- Dynamic routes: `pages/[id].tsx` -> `/:id`

**SvelteKit:**
- Files in `src/routes/` map directly: `src/routes/about/+page.svelte` -> `/about`
- Layout files (`+layout.svelte`) affect all child routes
- Server files (`+page.server.ts`) affect the corresponding route

**Nuxt:**
- Files in `pages/` map directly: `pages/dashboard.vue` -> `/dashboard`
- Layouts in `layouts/` affect routes that use them

**Django:**
- Changes to `views.py` require checking `urls.py` for the route mapping
- Changes to templates in `templates/` map to the view that renders them
- Changes to `urls.py` may add or remove routes entirely

**React (Vite/CRA with React Router):**
- Check the router configuration file for route-to-component mapping
- Component changes require tracing which routes render that component
- Shared components (used in multiple routes) affect all those routes

**Component dependency resolution:**
If a shared component changed (e.g., `components/Sidebar.tsx`), find all routes that import it:
```bash
# Find which files import the changed component
grep -rl "from.*Sidebar\|import.*Sidebar" --include="*.tsx" --include="*.jsx" --include="*.vue" --include="*.svelte" <project-root>/app <project-root>/pages <project-root>/src/routes
```

Map those importing files back to their routes to get the full affected route list.

**Global change detection:**
If any of these changed, ALL routes are affected:
- Root layout files (`app/layout.tsx`, `layouts/default.vue`)
- Global CSS/SCSS files
- Theme configuration files
- Navigation components (header, sidebar, footer)

Flag global changes and inform the user: "Global files changed. All routes need re-capture. This is equivalent to a full regeneration."

### Step 4: Check for Manual Edits

Before regenerating articles, check if any have been manually edited by the user.

**Manual edit markers:**
Scan existing article content for the `<!-- manual -->` marker. This marker indicates the user has hand-edited the article and does not want it auto-regenerated.

```
For each article in the manifest:
  Read the article content
  If content contains "<!-- manual -->" or "<!-- manual-edit -->" or "<!-- no-regen -->":
    Mark as PROTECTED
  Else:
    Mark as REGENERABLE
```

**Additional manual edit detection:**
If no explicit markers exist, check the git history of the output directory:
```bash
# Check if doc output files were modified outside of KodaDocs pipeline commits
git log --oneline --diff-filter=M -- <docs-output-dir>/*.md
```

If a doc file was modified in a commit that does not contain "kodadocs" or "docs-refresh" in the message, it may have been manually edited. Flag these as POSSIBLY_MANUAL and ask the user before overwriting.

**Build the regeneration plan:**

| Route | Screenshot Status | Article Status | Action |
|-------|------------------|----------------|--------|
| /dashboard | Stale (component changed) | REGENERABLE | Re-capture + Re-generate |
| /settings | Stale (page file changed) | PROTECTED (manual) | Re-capture only, keep article |
| /login | Current (no changes) | REGENERABLE | Skip entirely |
| /profile | Stale (layout changed) | POSSIBLY_MANUAL | Ask user before regenerating |

Present this plan to the user and ask for confirmation before proceeding.

### Step 5: Re-capture Affected Screenshots

For routes that need new screenshots, run the screenshot capture tool.

**Prepare the route list:**
Filter down to only routes marked for re-capture in the regeneration plan.

**Run capture:**
```
Call mcp__kodadocs__capture_screenshots with:
  routes: [<list of affected routes>]
  app_url: "<running application URL>"
  auth: <auth config from manifest, or null>
  output_dir: "<screenshots directory from manifest>"
  blur_pii: true
```

**Merge results:**
The new screenshots replace the old ones in the screenshots directory. Unchanged routes keep their existing screenshots.

If the application is not running:
- Warn: "Application not accessible at <url>. Cannot re-capture screenshots."
- Offer to proceed with article regeneration only (using existing screenshots)
- Offer to skip the refresh entirely until the app is available

### Step 6: Re-generate Affected Articles

Generate new article content for the affected routes while preserving unchanged articles.

**Load existing articles from the manifest:**
```
Call mcp__kodadocs__load_manifest with:
  project_path: "<project-root>"
```

Extract the `articles` array from the manifest.

**For each route in the regeneration plan:**

- **SKIP:** Route is unchanged -- keep the existing article as-is
- **PROTECTED:** Route has manual edits -- keep the existing article, update screenshots only
- **REGENERATE:** Route is affected and not protected -- generate a new article

**Analyze the codebase for context:**
```
Call mcp__kodadocs__analyze_codebase with:
  project_path: "<project-root>"
  discovered_routes: [<list of affected routes only>]
```

Use the code analysis results (code chunks, data models, error patterns) to generate accurate, context-aware articles for the affected routes.

**Article generation guidelines:**
- Match the tone and structure of existing articles for consistency
- If a style guide exists at `.kodadocs/style-guide.md`, follow it
- Include references to new screenshots where applicable
- Preserve the article ordering from the manifest

**Build the complete articles list:**
Merge the unchanged articles with the newly generated ones. The final list must include ALL articles (unchanged + updated), not just the updated ones.

### Step 7: Reassemble the Doc Site

Rebuild the VitePress site with the updated articles.

**Load full configuration from manifest:**
Extract: `project_name`, `brand_color`, `logo_path`, `output_dir`, `screenshots_dir`, `product_summary`, `discovered_routes`, and any other configuration.

**Call assemble:**
```
Call mcp__kodadocs__assemble_vitepress with:
  articles: [<complete articles list -- all articles, updated + unchanged>]
  screenshots_dir: "<screenshots directory>"
  brand_color: "<from manifest>"
  logo_path: "<from manifest or null>"
  output_dir: "<from manifest>"
  project_name: "<from manifest>"
  product_summary: "<from manifest>"
  discovered_routes: [<current full route list>]
```

Use the same configuration values from the manifest to ensure visual consistency.

### Step 8: Update the Manifest

Save the updated pipeline state so the next refresh knows where to start.

**Update the manifest with:**
- New `last_commit_sha` (the current HEAD)
- New `last_run_timestamp` (current ISO timestamp)
- Updated articles list
- Updated route list (from fresh discovery)
- A `refresh_history` entry recording what was changed:

```json
{
  "refresh_history": [
    {
      "timestamp": "2026-03-02T14:30:00Z",
      "commit_sha": "abc1234",
      "changed_files": 5,
      "affected_routes": ["/dashboard", "/settings"],
      "articles_regenerated": 2,
      "articles_preserved": 6,
      "manual_edits_kept": 1
    }
  ]
}
```

```
Call mcp__kodadocs__save_manifest with:
  project_path: "<project-root>"
  manifest: { <updated manifest object> }
```

### Step 9: Deploy (Optional)

If the user requests deployment or if auto-deploy is configured in the manifest:

```
Call mcp__kodadocs__deploy_site with:
  site_dir: "<output directory>"
  project_name: "<from manifest>"
  provider: "<from manifest>"
  license_key: "<from manifest or env>"
  site_slug: "<from manifest>"
```

If auto-deploy is not requested, inform the user: "Doc site rebuilt. Run deploy when ready."

## Decision Trees

### Change Scope Assessment

```
How many files changed?
  0 files -> "No changes detected since last doc generation. Nothing to refresh."
             Exit early.
  1-10 files -> Standard incremental refresh (this workflow)
  11-50 files -> Large changeset. Check for global changes first.
                 If global changes found -> Suggest full regeneration instead
                 If no global changes -> Proceed with incremental refresh
  50+ files -> "Major changes detected (N files). A full regeneration is recommended."
               Ask user: "Run full regeneration or attempt incremental?"
```

### Global vs. Targeted Refresh

```
Did a global file change? (root layout, global CSS, nav component, theme config)
  YES -> All routes are affected. This is effectively a full regeneration.
         Inform user: "Global files changed. All N routes will be re-captured."
         Ask: "Proceed with full re-capture, or skip screenshots and regenerate text only?"
  NO  -> Proceed with targeted route-level refresh
```

### Manual Edit Handling

```
Does the article contain <!-- manual --> marker?
  YES -> PROTECTED. Never overwrite.
         Re-capture screenshot only if the route's UI changed.
         Keep existing article content exactly as-is.
  NO  -> Was the article file modified outside KodaDocs?
           YES -> POSSIBLY_MANUAL. Ask user before overwriting.
                  "Article for /settings was modified manually. Overwrite with fresh generation?"
           NO  -> REGENERABLE. Safe to overwrite.
```

### Screenshot Availability

```
Is the application running at the configured URL?
  YES -> Re-capture screenshots for affected routes
  NO  -> Can the user start the app?
           YES -> Wait for user to start app, then re-capture
           NO  -> Skip screenshot re-capture
                  Use existing screenshots (may be stale)
                  Warn: "Screenshots for affected routes may be outdated"
```

### Manifest State

```
Does .kodadocs/run_manifest.json exist?
  YES -> Does it contain last_commit_sha?
           YES -> Use git diff from that SHA to HEAD
           NO  -> Does it contain last_run_timestamp?
                    YES -> Use git log --since=<timestamp>
                    NO  -> Fall back to user-specified range or last 7 days
  NO  -> "No previous doc generation found. Run a full pipeline first."
         Exit with error.
```

## Output Format

The skill produces:

1. **Regeneration plan** - A table showing which routes will be refreshed and why
2. **Updated screenshots** - New captures for affected routes only
3. **Updated articles** - Regenerated content for affected routes only
4. **Rebuilt doc site** - Reassembled VitePress output with all articles
5. **Updated manifest** - Pipeline state updated with current commit SHA and refresh history
6. **Console summary:**

```
Docs refresh complete:
  Changes detected: 7 files changed since abc1234
  Routes affected: 3 of 12 total
  Articles regenerated: 2
  Articles preserved (unchanged): 8
  Articles protected (manual edits): 2
  Screenshots re-captured: 3
  Refresh history entry saved
  Time saved vs. full regeneration: ~65%
  Output: <output-dir>
```

## Error Handling

### No manifest found
If `.kodadocs/run_manifest.json` does not exist:
- Stop and inform: "No previous documentation run found. Run the full KodaDocs pipeline first to establish a baseline."
- Do not attempt a partial generation without a manifest

### Git history unavailable
If `git diff` fails (not a git repo, shallow clone, etc.):
- Ask the user to specify which files or routes changed manually
- Proceed with the user-provided list instead of git diff

### Changed file cannot be mapped to a route
If a changed file does not match any known route pattern:
- Log it as "unmapped" in the refresh report
- If more than 50% of changed files are unmapped, suggest running `discover_routes` to update the route map

### Screenshot capture fails for some routes
If `capture_screenshots` succeeds for some routes but fails for others:
- Use the new screenshots for routes that succeeded
- Keep existing screenshots for routes that failed
- Warn: "Screenshot capture failed for /route-name. Using existing screenshot."
- Do not abort the entire refresh

### Protected article references a deleted route
If a manually edited article references a route that no longer exists:
- Do NOT delete the article (it has manual edits)
- Flag it in the report: "Warning: /old-route no longer exists but has a manually edited article"
- Let the user decide what to do with orphaned manual articles

### Manifest schema mismatch
If the manifest was created by an older version and is missing expected fields:
- Use sensible defaults for missing fields
- Warn: "Manifest appears to be from an older version. Some fields were set to defaults."
- After the refresh, save the updated manifest with the current schema

### Merge conflict between old and new articles
If the article list from the manifest conflicts with the current route list:
- New routes (in discover_routes but not in manifest): generate new articles
- Removed routes (in manifest but not in discover_routes): mark as orphaned, ask user
- Changed routes (in both): follow the regeneration plan

## Success Criteria

The run is successful when:
- [ ] Changed files were identified via git diff or user input
- [ ] Changed files were classified by documentation impact
- [ ] Affected routes were correctly mapped from changed files
- [ ] Manual edit markers were detected and respected
- [ ] A regeneration plan was presented to the user
- [ ] Screenshots were re-captured only for affected routes
- [ ] Articles were regenerated only for affected, non-protected routes
- [ ] Protected articles (with manual edit markers) were preserved unchanged
- [ ] The complete article list (updated + unchanged) was passed to assemble
- [ ] The VitePress site was successfully reassembled
- [ ] The manifest was updated with current commit SHA and refresh history
- [ ] Console summary was printed with refresh statistics
- [ ] Time savings over full regeneration were reported
