Back to the catalog

Knowledge Base

Bundle OKF 0.2 · 6 conceitos · jyjeanne/ditacraft

Open source Repository Open in the app JSON README (API)

About

# Knowledge Base

- [Classes](classes/index.md) (42)
- [Functions](functions/index.md) (1040)
- [Interfaces](interfaces/index.md) (178)
- [Modules](modules/index.md) (252)
- [Packages](packages/index.md) (3)
- [README](README.md)

Details

Kind
OKF bundles
Topic
AI, RAG & memory
Publisher
jyjeanne
Origin
okf_github
Category
dados
Version
0.2
Stars
17
Forks
6
Open pull requests
3
Last push
2026-09-07T23:45:08Z
Repository state
ativo
Language
TypeScript
License
MIT
Added
2026-09-08 02:17:33
Updated
2026-09-08 02:17:33
Origin id
jyjeanne/ditacraft:docs/okf-knowledge/index.md

README

# DitaCraft

**The easiest way to edit and publish your DITA files**

[![VS Code](https://img.shields.io/badge/VS%20Code-1.80+-blue.svg)](https://code.visualstudio.com/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![CI](https://github.com/jyjeanne/ditacraft/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/jyjeanne/ditacraft/actions/workflows/ci.yml)
[![Version](https://img.shields.io/badge/version-0.9.0-orange.svg)](CHANGELOG.md)

DitaCraft is a comprehensive Visual Studio Code extension for editing and publishing DITA (Darwin Information Typing Architecture) content. It provides syntax highlighting, real-time validation, smart navigation, AI-powered assistance, an MCP server for external AI agents, and seamless integration with DITA-OT for multi-format publishing.

## Table of Contents

- [Highlights](#highlights)
- [Features](#features)
  - [Language Server Protocol (LSP)](#%EF%B8%8F-language-server-protocol-lsp)
  - [AI-Powered Features](#-ai-powered-features-github-copilot-integration)
  - [Smart Navigation](#-smart-navigation)
  - [Advanced Validation](#-advanced-validation)
  - [One-Click Publishing](#-one-click-publishing)
  - [Live Preview](#%EF%B8%8F-live-preview)
  - [Activity Bar Views](#-activity-bar-views)
  - [Map Visualizer](#%EF%B8%8F-map-visualizer)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Commands](#commands)
- [Configuration](#configuration)
- [AI Provider Configuration](#ai-provider-configuration)
- [MCP Server Integration](#mcp-server-integration-external-ai-agents)
- [Development](#development)
- [Roadmap](#roadmap)
- [License](#license)

## Highlights

🔗 **Smart Navigation** - Ctrl+Click on `href`, `conref`, `keyref`, and `conkeyref` attributes with full key space resolution
🔑 **Key Space Resolution** - Full DITA 1.3 spec-compliant key space construction: keyref chains, keyscope inheritance (PushDown), inline scope branches, provenance tracking, scope explosion protection (50 k cap), and `explainKey()` resolution diagnostics
✅ **13-Phase Validation Pipeline** - DTD (TypesXML) + optional RelaxNG (salve-annos) + 43 DITA rules + custom rules with DITA 1.2/1.3/2.0 support, per-phase error isolation, severity overrides, and comment-based suppression
🌍 **Localized Diagnostics** - All 76+ diagnostic messages translatable (English + French included)
⚡ **Real-time Validation** - Smart debouncing (300ms topics, 1000ms maps) with per-document cancellation
🔒 **Enterprise Security** - Path traversal protection, XXE neutralization, command injection prevention, and quote-aware entity pre-checks (billion-laughs / XXE bypass-proof)
🚀 **One-Click Publishing** - Direct DITA-OT integration for HTML5, PDF, EPUB, and more
👁️ **Live Preview** - Side-by-side HTML5 preview with auto-refresh and bidirectional scroll sync
🗺️ **Map Visualizer** - Interactive tree view of DITA map hierarchies with navigation
📂 **Activity Bar Views** - DITA Explorer, Key Space, and Diagnostics views in dedicated sidebar
📝 **21 Smart Snippets** - Comprehensive DITA code snippets for rapid editing
🛡️ **Rate Limiting** - Built-in DoS protection for validation operations
🤖 **AI-Powered Features** - GitHub Copilot integration: `@ditacraft` chat participant, AI Quick Fix, AI Completion, map restructuring, and multi-provider cascade (Copilot → Anthropic → OpenAI → Ollama)
🔌 **MCP Server** - Standalone Model Context Protocol server for external AI agents (opencode, Claude Desktop, Cursor, Continue) — 6 tools, 3 resources, zero VS Code dependency
🧪 **2183+ Tests** - Extensively tested with comprehensive integration, security, and LSP server tests
📚 **DITA User Guide** - Comprehensive documentation written in DITA (~80 files, bookmap structure)

## Features

### 🖥️ **Language Server Protocol (LSP)**
- Full-featured DITA Language Server running in a separate process for performance
- **IntelliSense**: Context-aware element, attribute, and value completions with subject scheme hierarchy grouping
- **Hover**: Element documentation tooltips from DITA schema with conref content preview
- **Document Symbols**: Hierarchical outline view (Ctrl+Shift+O)
- **Workspace Symbols**: Cross-file symbol search (Ctrl+T)
- **Go to Definition**: Navigate to href/conref/keyref targets with key space resolution
- **Find References**: Locate all usages of an element ID across files
- **Rename**: Rename IDs with automatic reference updates across workspace
- **Formatting**: XML document formatting with inline/block/preformatted handling
- **Code Actions**: 12 quick fixes for missing DOCTYPE, missing ID, missing title, empty elements, duplicate IDs, missing otherrole, deprecated indextermref, alt attribute conversion, missing alt text, invalid ID format sanitization, missing booktitle, missing mainbooktitle
- **Linked Editing**: Simultaneous open/close XML tag name editing
- **Folding Ranges**: Collapse XML elements, comments, and CDATA blocks
- **Document Links**: Clickable href/conref/keyref links with key resolution
- **Diagnostics**: XML well-formedness, DITA structure, ID, cross-reference, scope consistency, circular reference detection, DITA rules (43 Schematron-equivalent rules including DITA 2.0), profiling/subject scheme, DTD (OASIS catalog with DITA 1.2/1.3/2.0), optional RelaxNG, workspace-level analysis, DITAVAL validation, custom regex rules, per-rule severity overrides, and comment-based rule suppression
- **Localization**: All diagnostic messages translatable via i18n system (English + French)

### 🤖 **AI-Powered Features** (GitHub Copilot Integration)
- **`@ditacraft` Chat Participant** — Interact with your DITA workspace directly in GitHub Copilot Chat:
  - `/restructure` — AI-driven DITA map reorganization with diff review before applying
  - `/validate` — Get AI explanations for validation errors with fix suggestions
  - `/explain` — Plain-language explanations of DITA structure and element usage
  - `/suggest-reuse` — Find content reuse opportunities (shared topics, conrefs)
- **F2: AI Map Restructure** — Bound to `ditacraft.restructureMap`; AI proposes a restructured map hierarchy; shows diff and asks for confirmation before writing
- **F3: AI Quick Fix** — AI-generated fixes for 12 diagnostic codes (CM-001/002/003, XREF-001/003/004, STRUCT-003/004/005/008, DTD-001, XML-001) via Code Actions → "Fix with AI"
- **F4: AI Completion** — Enriched IntelliSense: AI suggests element content and attribute values in context
- **Provider Cascade** — Auto mode: Copilot → Anthropic → OpenAI → Ollama; supports `copilot-only`, `byok-only`, `local-only` modes
- **Circuit Breaker** — Per-provider resilience: 3 failures in 5 min opens the breaker (10 min cooldown); zero-dependency on unavailable providers
- **Streaming Support** — AI responses stream in real time via `vscode.lm` (Copilot) or server-sent events (Anthropic/OpenAI); Ollama uses `/api/generate` with streaming chunks
- **Metrics Dashboard** — Request counts, latency, and error rates per provider; visible in the Configure AI panel
- **DitaCraft: Configure AI** — Guided setup for provider selection, API keys (stored securely via OS keychain), and feature toggles

### ✍️ **Syntax Highlighting & Snippets**

- Syntax highlighting for `.dita`, `.ditamap`, `.bookmap`, and `.ditaval` files
- Intelligent code snippets and auto-completion (21 comprehensive snippets)
- Support for all DITA topic types (concept, task, reference, topic, glossentry, troubleshooting)

### 🔗 **Smart Navigation**
- **Ctrl+Click navigation** in DITA maps, bookmaps, and topics
  - Click on `href` attributes in `<topicref>` elements to open referenced files
  - Click on `conref` attributes to navigate to content references
  - Click on `keyref` and `conkeyref` to navigate to key-defined targets
  - Works with relative paths and handles fragment identifiers (e.g., `file.dita#topic_id`)
  - Visual link indicators (underlined references when you hover)
  - Hover tooltip showing target filename and reference type
  - Automatically resolves paths relative to the map file location
  - Skips external URLs (http://, https://) - they won't be underlined
- **Full Key Space Resolution** (complete as of v0.7.4)
  - Automatically discovers root maps in your workspace
  - Builds and caches key space from map hierarchies (DITA 1.3 spec-compliant BFS)
  - Resolves `@keyref`, `@conkeyref`, and key-based references including multi-hop keyref chains
  - Full `@keyscope` support: PushDown inheritance, inline scope branches, qualified alias explosion cap (50,000 keys)
  - Provenance tracking: each key definition records its source line for diagnostics
  - `explainKey()` API returns a full `KeyResolutionReport` with lookup trace and keyref chain steps
  - Tiered caching (1-minute root map discovery, 5-minute key space TTL) with intelligent invalidation
- Navigate seamlessly between maps and topics in your documentation structure
- **How to use:**
  1. Open a `.ditamap`, `.bookmap`, or `.dita` file
  2. Hover over any `href`, `conref`, `keyref`, or `conkeyref` value - it will be underlined
  3. Ctrl+Click (Windows/Linux) or Cmd+Click (Mac) to open the target file
  4. Works with nested topicrefs, key definitions, and complex map structures

### ✅ **Advanced Validation**
- **Real-time validation** on file open, save, and change with smart debouncing (300ms topics, 1000ms maps)
- **Full DTD validation** against DITA 1.2, 1.3, and 2.0 specifications using TypesXML
  - Bundled DTDs for all three DITA versions (topic, concept, task, reference, map, bookmap, learning, etc.)
  - Master OASIS XML Catalog with `<nextCatalog>` chaining — auto-resolves PUBLIC IDs for any DITA version
  - Custom XML catalog support (`ditacraft.xmlCatalogPath`) for DTD specializations
  - Parser pool (3 concurrent instances) for efficient reuse
  - 100% W3C XML Conformance Test Suite compliance
- **Optional RelaxNG validation** using salve-annos + saxes
  - Schema compilation with caching (max 20 grammars, JSON cache files)
  - Root element to RNG schema auto-mapping (10 DITA element types)
  - Configurable schema directory path
- **43 DITA rules** (Schematron-equivalent) with DITA version awareness + custom regex rules
  - 4 mandatory rules, 7 recommendation rules, 2 authoring rules, 8 accessibility rules
  - 10 DITA 2.0 removal/migration rules (deprecated elements and attributes)
  - Version-gated: rules apply only to relevant DITA versions
  - Precise attribute-level diagnostic highlighting
  - **Custom regex rules** from user-defined JSON file with fileType filtering and mtime-based caching
  - **Per-rule severity overrides** — change any diagnostic code's severity or suppress it entirely
  - **Comment-based rule suppression** — `<!-- ditacraft-disable CODE -->` / `<!-- ditacraft-enable CODE -->` / `<!-- ditacraft-disable-file CODE -->`
  - **Large file optimization** — heavy validation phases skipped for files exceeding configurable size threshold
- **Three validation engines**:
  - **TypesXML** (default, recommended) - Pure TypeScript DTD validation with no native dependencies
  - Built-in parser with content model checking (lightweight, no full DTD)
  - xmllint integration for external validation (requires libxml2 installation)
- **DITA version detection**: Auto-detects from `@DITAArchVersion` attribute or DOCTYPE declaration
- **Scope validation**: Validates `scope="local|peer|external"` consistency with href format (DITA-SCOPE-001/002/003)
- **Circular reference detection**: Detects href/conref/mapref cycles using DFS traversal (DITA-CYCLE-001)
- **Workspace-level analysis**:
  - `DITA: Validate Workspace` command with progress reporting
  - Cross-file duplicate root ID detection (DITA-ID-003)
  - Unused topic detection — finds topics not referenced by any map (DITA-ORPHAN-001)
- **Enterprise Security Features**:
  - XXE (XML External Entity) neutralization to prevent injection attacks
  - Path traversal protection with workspace bounds validation
  - Command injection prevention using safe execution methods
  - Async file operations to prevent LSP event loop blocking
  - Quote-aware entity pre-check — `]>` inside quoted entity values cannot bypass billion-laughs or excessive-entity-count detection (defense-in-depth, CVE-class)
- **Intelligent error highlighting**:
  - Inline error highlighting with squiggly underlines
  - Errors appear in Problems panel with severity indicators
  - Accurate line and column positioning
  - Source attribution (DTD validator, XML parser, DITA validator, dita-rules)
- **Auto-detection of DITA files**:
  - By extension: `.dita`, `.ditamap`, `.bookmap`, `.ditaval`
  - By DOCTYPE: Recognizes DITA DOCTYPE declarations in `.xml` files
- **Manual validation command**: `DITA: Validate Current File` (Ctrl+Shift+V / Cmd+Shift+V)

### 🚀 **One-Click Publishing**
- Publish to multiple formats: HTML5, PDF, EPUB, and more
- Direct integration with DITA Open Toolkit (DITA-OT)
- Real-time progress tracking with visual indicators
- Smart caching for faster preview generation

### 👁️ **Live Preview**
- Side-by-side HTML5 preview with WebView panel
- Auto-refresh on save with configurable behavior
- **Bidirectional scroll sync** - Editor and preview scroll positions stay synchronized
- **Theme support** - Light, dark, and auto modes (follows VS Code theme)
- **Custom CSS** - Apply custom stylesheets to preview
- **Print preview mode** - Print-optimized view with dedicated print button
- Navigate directly from source to preview

### 📊 **Build Output**
- **Syntax-highlighted output** - DITA-OT build output with automatic colorization
- **Log level detection** - Errors, warnings, info, and debug messages color-coded
- **Error diagnostics** - Build errors parsed and shown in Problems panel
- **Timestamped builds** - Build start and completion times displayed
- **Validation report** - Full guide validation results in WebView panel with filtering, search, and export

### 📂 **Activity Bar Views**
- **DitaCraft sidebar** in the Activity Bar with three dedicated tree views
- **DITA Explorer** — All workspace maps with expandable hierarchy, type icons, click-to-open navigation
- **Key Space View** — Defined, undefined, and unused keys with usage locations and key scope support
- **Diagnostics View** — Aggregated DITA issues, group by file or severity, click-to-navigate
- **Root Map Selector** — Status bar indicator with click-to-set, auto-discover or explicit mode
- **File decorations** — Error/warning badges on tree items from validation diagnostics
- **Welcome content** — Helpful actions shown when views are empty
- Auto-refresh on file and diagnostics changes with debouncing

### 🗺️ **Map Visualizer**
- **Interactive tree view** - Visual hierarchy of DITA maps, bookmaps, and topics
- **Element type icons** - Different icons for maps, chapters, appendices, parts, topics, keys, and glossrefs
- **Missing file detection** - Missing referenced files shown with strikethrough styling
- **Circular reference protection** - Detects and marks circular map references
- **Double-click navigation** - Open any topic or map directly from the visualizer
- **Expand/Collapse controls** - Easily navigate large map hierarchies
- **Real-time refresh** - Update the visualization when map content changes

### 🎯 **Quick File Creation**
- Create DITA topics from templates (concept, task, reference)
- Generate DITA maps and bookmaps with proper structure
- Pre-filled DOCTYPE declarations and valid XML structure

### ⚙️ **Flexible Configuration**
- Configure DITA-OT installation path
- Customize output formats and directories
- Add custom DITA-OT arguments and filters
- Choose validation engine (xmllint or built-in)

## Installation

### From VS Code Marketplace
1. Open VS Code
2. Press `Ctrl+P` / `Cmd+P`
3. Type `ext install ditacraft`
4. Press Enter

### From VSIX
1. Download the latest `.vsix` file from [Releases](https://github.com/jyjeanne/ditacraft/releases)
2. Open VS Code
3. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`)
4. Click `...` menu → "Install from VSIX..."
5. Select the downloaded file

### Local Installation for Development

If you want to install the plugin locally from source code for development or testing:

#### Step 1: Prerequisites
Ensure you have the following installed:
- **Node.js** 18.x or 20.x ([Download](https://nodejs.org/))
- **npm** (comes with Node.js)
- **VS Code** 1.80 or higher
- **Git** (optional, for cloning)

#### Step 2: Get the Source Code
```bash
# Clone the repository (or download ZIP from GitHub)
git clone https://github.com/jyjeanne/ditacraft.git
cd ditacraft

# OR if you downloaded as ZIP:
# Extract the ZIP file and navigate to the extracted folder
cd DitaCraft
```

#### Step 3: Install Dependencies
```bash
npm install
```
This will install all required npm packages (~429 packages).

#### Step 4: Compile TypeScript
```bash
npm run compile
```
This compiles the TypeScript source code to JavaScript in the `out/` directory.

#### Step 5: Package the Extension
```bash
npm run package
```
This creates a `.vsix` file in the project root (e.g., `ditacraft-0.1.0.vsix`).

**Note:** If you don't have `vsce` installed, install it first:
```bash
npm install -g @vscode/vsce
```

#### Step 6: Install in VS Code
**Option A: Install from VSIX**
1. Open VS Code
2. Press `Ctrl+Shift+X` (or `Cmd+Shift+X` on macOS) to open Extensions
3. Click the `...` menu at the top right
4. Select "Install from VSIX..."
5. Navigate to your project folder
6. Select the `ditacraft-0.1.0.vsix` file
7. Click "Install"
8. Reload VS Code when prompted

**Option B: Run in Development Mode** (Recommended for testing)
1. Open the `ditacraft` folder in VS Code
2. Press `F5` (or Run → Start Debugging)
3. A new VS Code window opens with the extension loaded
4. Test the extension in this window
5. Make changes to code, save, and press `Ctrl+R` in the Extension Host window to reload

#### Step 7: Verify Installation
1. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`)
2. Type "DITA" - you should see all DitaCraft commands
3. Try creating a new topic: "DITA: Create New Topic"

#### Step 8: Configure DITA-OT (Optional, for publishing)
1. Download DITA-OT from https://www.dita-ot.org/download
2. Extract to a location (e.g., `C:\DITA-OT-4.2.1`)
3. In VS Code, run "DITA: Configure DITA-OT Path"
4. Select your DITA-OT installation directory

### Troubleshooting Local Installation

#### Issue: `npm install` fails
**Solution:**
- Check Node.js version: `node --version` (should be 18.x or 20.x)
- Clear npm cache: `npm cache clean --force`
- Delete `node_modules` and `package-lock.json`, then run `npm install` again

#### Issue: Compilation errors
**Solution:**
- Ensure TypeScript is installed: `npm install -g typescript`
- Check for syntax errors in `.ts` files
- Run `npm run lint` to check for code issues

#### Issue: Extension not appearing in VS Code
**Solution:**
- Verify the `.vsix` file was created successfully
- Check VS Code version is 1.80 or higher
- Try uninstalling any existing version first
- Restart VS Code completely

#### Issue: "Cannot find module" errors
**Solution:**
- Run `npm install` again
- Check that `node_modules` directory exists
- Verify `package.json` has all dependencies

### Development Workflow

For active development on the extension:

```bash
# Terminal 1: Watch mode (auto-compile on changes)
npm run watch

# Terminal 2: Run extension in debug mode
# Press F5 in VS Code (or Run → Start Debugging)
```

**Making Changes:**
1. Edit TypeScript files in `src/`
2. Watch mode auto-compiles to `out/`
3. In Extension Host window, press `Ctrl+R` (or `Cmd+R`) to reload
4. Test your changes

**Running Tests:**
```bash
npm test
```

**Linting Code:**
```bash
npm run lint
```

## Prerequisites

### Required
- **VS Code** 1.80 or higher
- **Node.js** 18.x or 20.x (for development)

### For Publishing
- **DITA-OT** 4.2.1 or higher ([Download](https://www.dita-ot.org/download))

### For Alternative Validation (Optional)
- **xmllint** (libxml2) for external XML validation (TypesXML is the default and recommended engine)

## Quick Start

### 1. Install DITA-OT
Download and install DITA-OT from https://www.dita-ot.org/download

### 2. Configure DitaCraft
1. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`)
2. Type "DITA: Configure DITA-OT Path"
3. Select your DITA-OT installation directory

### 3. Create Your First DITA File
1. Open Command Palette
2. Type "DITA: Create New Topic"
3. Select topic type (concept, task, reference)
4. Enter file name

### 4. Publish
1. Open your `.dita`, `.ditamap`, or `.bookmap` file
2. Press `Ctrl+Shift+B` / `Cmd+Shift+B`
3. Select output format (HTML5, PDF, etc.)
4. View published content

## Commands

All commands are accessible via Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`):

| Command | Shortcut | Description |
|---------|----------|-------------|
| **DITA: Validate Current File** | `Ctrl+Shift+V` | Validate DITA syntax and structure |
| **DITA: Publish (Select Format)** | `Ctrl+Shift+B` | Publish with format selection |
| **DITA: Publish to HTML5** | - | Quick publish to HTML5 |
| **DITA: Preview HTML5** | `Ctrl+Shift+H` | Show live HTML5 preview |
| **DITA: Show Map Visualizer** | - | Show interactive map hierarchy |
| **DITA: Create New Topic** | - | Create new DITA topic |
| **DITA: Create New Map** | - | Create new DITA map |
| **DITA: Create New Bookmap** | - | Create new bookmap |
| **DITA: Configure DITA-OT Path** | - | Set DITA-OT installation path |
| **DITA: Set Root Map** | - | Choose explicit root map for key resolution |
| **DITA: Clear Root Map** | - | Revert to automatic root map discovery |
| **DITA: Validate Workspace** | - | Validate all DITA files across workspace |
| **DITA: Validate Entire Guide** | - | Full DITA-OT validation of root map with report panel |
| **DITA: Configure AI Settings** | - | Configure AI provider, API keys, and feature toggles |
| **DITA: Restructure Map with AI** | `F2` | AI-driven map restructuring with diff review |
| **DITA: Setup cSpell Configuration** _(deprecated)_ | - | Create a lean cSpell config for DITA files |

## Spell Checking with cSpell

DitaCraft provides a lean `.cspellrc.json` template that works alongside the LSP server. Rather than maintaining a large DITA word list (which is now handled by the LSP), the configuration uses regex-based patterns to silently ignore XML tags and attribute syntax, so cSpell focuses exclusively on prose spelling errors in your content.

### What the config does

The generated `.cspellrc.json`:
- **Suppresses XML tag noise** — ignores `<element-name>` and `attr="value"` patterns inside DITA files via `ignoreRegExpList`, so cSpell doesn't flag DITA markup as misspelled words
- **Leaves prose spell-checking intact** — actual text content in `<p>`, `<title>`, `<shortdesc>`, etc. is still checked
- **Includes a TypeScript word allowlist** — common DITA/LSP terms (`dita`, `keyref`, `conref`, `oasis`, `vscode`, etc.) allowed in `.ts` source files
- **Ignores generated/binary paths** — `node_modules`, `out`, `dist`, `.git`, `*.ditaval` excluded

> **Note:** The `DITA: Setup cSpell Configuration` command is deprecated. The DITA Language Server now handles DITA vocabulary validation; cSpell is only needed for prose spell-checking.

### Setup cSpell

**Option 1: Run the command** _(still works, now creates the lean config)_
1. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`)
2. Type "DITA: Setup cSpell Configuration"
3. Click the command — DitaCraft creates a `.cspellrc.json` in your workspace root

**Option 2: Manual setup**

Create `.cspellrc.json` at your workspace root:
```json
{
  "version": "0.2",
  "language": "en",
  "ignorePaths": ["node_modules", "out", "dist", ".git", ".vscode-test", "*.ditaval"],
  "overrides": [
    {
      "filename": "**/*.{dita,ditamap,bookmap,xml}",
      "ignoreRegExpList": ["<[^>]+>", "\\s[a-zA-Z-]+=(\"[^\"]*\"|'[^']*')"]
    },
    {
      "filename": "src/**/*.ts",
      "words": ["dita","dtd","conref","keyref","topicref","ditamap","xml","xpath","oasis","vscode","textmate"]
    }
  ]
}
```

## Configuration

### Basic Settings

```json
{
    "ditacraft.ditaOtPath": "C:\\DITA-OT-4.2.1",
    "ditacraft.defaultTranstype": "html5",
    "ditacraft.outputDirectory": "${workspaceFolder}/out"
}
```

### All Settings

| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `ditacraft.ditaOtPath` | string | `""` | DITA-OT installation path |
| `ditacraft.defaultTranstype` | string | `"html5"` | Default output format |
| `ditacraft.outputDirectory` | string | `"${workspaceFolder}/out"` | Output directory |
| `ditacraft.autoValidate` | boolean | `true` | Auto-validate on save |
| `ditacraft.previewAutoRefresh` | boolean | `true` | Auto-refresh preview |
| `ditacraft.previewScrollSync` | boolean | `true` | Bidirectional scroll sync |
| `ditacraft.previewTheme` | string | `"auto"` | Preview theme (auto/light/dark) |
| `ditacraft.previewCustomCss` | string | `""` | Custom CSS for preview |
| `ditacraft.showProgressNotifications` | boolean | `true` | Show progress notifications |
| `ditacraft.validationEngine` | string | `"built-in"` | Validation engine (built-in/typesxml/xmllint) |
| `ditacraft.ditaOtArgs` | array | `[]` | Custom DITA-OT arguments |
| `ditacraft.enableSnippets` | boolean | `true` | Enable code snippets |
| `ditacraft.maxNumberOfProblems` | number | `100` | Maximum diagnostics per file |
| `ditacraft.ditaRulesEnabled` | boolean | `true` | Enable Schematron-equivalent DITA rules |
| `ditacraft.ditaRulesCategories` | string[] | all | Rule categories to activate (mandatory, recommendation, authoring, accessibility) |
| `ditacraft.crossRefValidationEnabled` | boolean | `true` | Validate cross-file references (href, conref, keyref) |
| `ditacraft.subjectSchemeValidationEnabled` | boolean | `true` | Validate attribute values against subject schemes |
| `ditacraft.rootMap` | string | `""` | Explicit root map path (relative to workspace). Empty = auto-discover |
| `ditacraft.xmlCatalogPath` | string | `""` | Path to external XML catalog for custom DTD specializations |
| `ditacraft.validationSeverityOverrides` | object | `{}` | Per-rule severity overrides (e.g., `{"DITA-SCH-001": "hint", "DITA-ID-002": "off"}`) |
| `ditacraft.largeFileThresholdKB` | number | `500` | Skip heavy validation phases for files larger than this (0 = disabled) |
| `ditacraft.customRulesFile` | string | `""` | Absolute path to a JSON file defining custom regex validation rules |

📖 **See the [All Settings](#all-settings) reference table above for the full list of configuration options.**

## AI Provider Configuration

DitaCraft supports four LLM backends with automatic fallback. This section shows how to set up each one.

### Provider Overview

| Provider | Requires | Privacy | Best For |
|----------|----------|---------|----------|
| **GitHub Copilot** | Active Copilot subscription | Data sent to GitHub | Default — zero config |
| **Anthropic Claude** | `ANTHROPIC_API_KEY` (BYOK) | Data sent to Anthropic | Best reasoning quality |
| **OpenAI (ChatGPT / GPT-4o)** | `OPENAI_API_KEY` (BYOK) | Data sent to OpenAI | Broad compatibility |
| **Ollama (local)** | Ollama running on your machine | **Stays local** | Air-gapped / privacy-first |

The active mode is set with `ditacraft.ai.mode`:

```json
{
  "ditacraft.ai.mode": "auto"
}
```

| Value | Behaviour |
|-------|-----------|
| `"auto"` | Copilot first, then Anthropic, then OpenAI, then Ollama |
| `"copilot-only"` | Only GitHub Copilot (error if no Copilot subscription) |
| `"byok-only"` | Only Anthropic / OpenAI (skips Copilot entirely) |
| `"local-only"` | Only Ollama — **no data leaves your machine** |

---

### 🤖 GitHub Copilot (Default — No Setup Required)

DitaCraft uses the built-in `vscode.lm` API; no npm package or API key needed.

**Requirements:**
- GitHub Copilot extension installed and signed in
- Active Copilot Individual, Business, or Enterprise subscription

**Steps:**
1. Install the [GitHub Copilot extension](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot)
2. Sign in with your GitHub account
3. DitaCraft auto-detects Copilot and uses it immediately — nothing else to configure

**Optional override (to use a specific Copilot model):**
```json
{
  "ditacraft.ai.mode": "copilot-only"
}
```

---

### 🧠 Anthropic Claude (BYOK)

Claude is the highest-quality model available for structured content tasks like DITA map restructuring.

**Supported models:** `claude-3-5-sonnet-20241022` (default), `claude-3-opus-20240229`, `claude-3-haiku-20240307`

**Steps:**
1. Get an API key from [console.anthropic.com](https://console.anthropic.com/)
2. Open the Command Palette and run **DitaCraft: Configure AI Settings**
3. In the panel, paste your key into the **Anthropic** field and click **Save Key**
4. The key is stored in your OS keychain via `vscode.SecretStorage` — never in `settings.json`
5. Optionally choose your model:

```json
{
  "ditacraft.ai.mode": "byok-only",
  "ditacraft.ai.provider.anthropic.model": "claude-3-5-sonnet-20241022"
}
```

> **Key format:** Anthropic API keys start with `sk-ant-`. Keys not matching this prefix are rejected before any network call.

---

### 💬 OpenAI / ChatGPT (BYOK)

Supports GPT-4o (default), GPT-4 Turbo, and other OpenAI Chat Completions models.

**Supported models:** `gpt-4o` (default), `gpt-4-turbo`, `gpt-4`, `gpt-3.5-turbo`

**Steps:**
1. Get an API key from [platform.openai.com](https://platform.openai.com/api-keys)
2. Run **DitaCraft: Configure AI Settings** from the Command Palette
3. Paste your key into the **OpenAI** field and click **Save Key**
4. Optionally set the model:

```json
{
  "ditacraft.ai.mode": "byok-only",
  "ditacraft.ai.provider.openai.model": "gpt-4o"
}
```

> **OpenAI-compatible APIs (LM Studio, Jan, etc.):** These are not yet supported natively, but you can expose them via Ollama's OpenAI-compatible proxy endpoint in the meantime.

---

### 🏠 Local LLM with Ollama (Air-Gapped / Privacy Mode)

Ollama lets you run open-source models entirely on your machine — no data ever leaves your computer.

**Install Ollama:** [ollama.ai](https://ollama.ai)

**Recommended DITA-capable models:**

| Model | Command | Context | Notes |
|-------|---------|---------|-------|
| `llama3` | `ollama pull llama3` | 8 k | Default; good general quality |
| `llama3.1` | `ollama pull llama3.1` | 128 k | Large context — better for big maps |
| `mistral` | `ollama pull mistral` | 8 k | Fast, lighter footprint |
| `codellama` | `ollama pull codellama` | 16 k | Good for XML/structured content |
| `gemma3` | `ollama pull gemma3` | 8 k | Google Gemma 3 (open weights) |
| `phi3` | `ollama pull phi3` | 8 k | Microsoft Phi-3; compact and fast |

**Steps:**
1. Install and start Ollama: `ollama serve`
2. Pull your preferred model: `ollama pull llama3`
3. Configure DitaCraft:

```json
{
  "ditacraft.ai.mode": "local-only",
  "ditacraft.ai.provider.ollama.enabled": true,
  "ditacraft.ai.provider.ollama.baseUrl": "http://localhost:11434",
  "ditacraft.ai.provider.ollama.model": "llama3"
}
```

4. Run **DitaCraft: Configure AI Settings** and click **Test Connection** to verify Ollama is reachable

**Custom Ollama endpoint (remote server / Docker):**
```json
{
  "ditacraft.ai.provider.ollama.baseUrl": "http://my-gpu-server:11434"
}
```

> **Gemini via Ollama:** Google does not publish full Gemini weights, but you can run `gemma3` (Google's open-weights model) locally via `ollama pull gemma3`. For cloud Gemini (Gemini 1.5 Pro etc.), native support is planned in a future release.

---

### ☁️ Gemini (Google) — Planned

Native Google Gemini support (`gemini-1.5-pro`, `gemini-1.5-flash`) is planned for a future release via the Google Generative AI SDK.

**Workarounds available today:**
- **Local Gemma** — run Google's open-weights model via Ollama: `ollama pull gemma3`
- **OpenAI-compatible proxy** — expose Gemini through a proxy that implements the OpenAI Chat Completions API

Track progress: see the [Roadmap](ROADMAP.md#milestone-7-publishing-enhancements-v090) section.

---

### ⚙️ Full AI Settings Reference

```json
{
  "ditacraft.ai.enabled": true,
  "ditacraft.ai.mode": "auto",
  "ditacraft.ai.provider.anthropic.model": "claude-3-5-sonnet-20241022",
  "ditacraft.ai.provider.openai.model": "gpt-4o",
  "ditacraft.ai.provider.ollama.enabled": true,
  "ditacraft.ai.provider.ollama.baseUrl": "http://localhost:11434",
  "ditacraft.ai.provider.ollama.model": "llama3",
  "ditacraft.ai.context.maxTokens": 8000,
  "ditacraft.ai.quickfix.enabled": true,
  "ditacraft.ai.completion.enabled": true,
  "ditacraft.ai.streaming.enabled": true
}
```

---

## MCP Server Integration (External AI Agents)

DitaCraft exposes its DITA intelligence — validation, key space, context snapshots — over the **Model Context Protocol (MCP)**, letting external AI coding agents read and query your DITA workspace.

> **Status:** MCP server is **available** since v0.8.0 (current release: v0.9.0). Build with `npm run build-standalone` to produce `dist/mcp-server.js` and `dist/lsp-server.js`.

### What is MCP?

[Model Context Protocol](https://modelcontextprotocol.io) is an open standard (by Anthropic) that lets AI agents call tools and read resources from external servers. Compatible agents include **opencode**, **Claude Desktop**, **Continue**, **Cursor**, and any MCP-aware tool.

### DitaCraft MCP Server

Run `npm run build-standalone` then configure your agent:

| Tool | Description |
|------|-------------|
| `dita_validate` | Validate a DITA file or XML fragment and return diagnostics |
| `dita_context_snapshot` | Token-budgeted map snapshot for LLM injection (L1/L2/L3) |
| `dita_key_space` | List all defined keys and their resolved targets |
| `dita_map_structure` | Return the full topic hierarchy (JSON/tree/CSV) |
| `dita_resolve_reference` | Resolve an href/keyref/conref/conkeyref to its target |
| `dita_explain_key` | Detailed step-by-step key resolution trace |

| Resource | Description |
|----------|-------------|
| `dita://workspace/maps` | All DITA maps in the workspace |
| `dita://workspace/diagnostics` | Current validation diagnostics |
| `dita://workspace/keys` | Full key space |

### Using DitaCraft with opencode

```jsonc
// ~/.config/opencode/opencode.json
{
  "mcpServers": {
    "ditacraft": {
      "command": "node",
      "args": ["/path/to/ditacraft/dist/mcp-server.js"],
      "env": {
        "WORKSPACE": "/home/user/projects/my-dita-docs"
      }
    }
  }
}
```

```
> @ditacraft validate topics/intro.dita
> @ditacraft show me the map structure as a tree
> @ditacraft explain why keyref install-guide isn't resolving
```

### Using DitaCraft with Claude Desktop

```json
// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
// Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "ditacraft": {
      "command": "node",
      "args": ["/absolute/path/to/dist/mcp-server.js"],
      "env": { "WORKSPACE": "/path/to/dita/project" }
    }
  }
}
```

### Standalone LSP Server

DitaCraft also ships a **standalone LSP server** bundle for embedding in other Node.js projects:

```bash
npm run build-standalone
# → dist/lsp-server.js (2.0 MB) — self-contained, no node_modules needed

# Launch as headless LSP server:
node dist/lsp-server.js --stdio
```

Embed in any Node.js LSP client via `child_process.spawn`:

```js
const { spawn } = require('child_process');
const server = spawn('node', ['lsp-server.js', '--stdio'], {
    env: { DITACRAFT_EXTENSION_ROOT: __dirname },
});
// Communicate via server.stdin / server.stdout using vscode-languageserver
```

## Supported Output Formats

DitaCraft supports all DITA-OT transtypes:

- **HTML5** - Modern responsive HTML
- **PDF** - PDF via Apache FOP
- **XHTML** - XHTML output
- **EPUB** - EPUB3 e-books
- **HTML Help** - Windows CHM files
- **Markdown** - Markdown conversion

Additional formats available through DITA-OT plugins.

## Workflows

### Navigating Your Documentation Structure

1. Open a `.ditamap` or `.bookmap` file
2. **Ctrl+Click** (Cmd+Click on Mac) on any `href` attribute value in `<topicref>` elements
3. The referenced topic file opens in a new tab
4. Navigate back and forth between map and topics seamlessly

**Example:**
```xml
<map>
    <topicref href="introduction.dita"/>     <!-- Ctrl+Click opens introduction.dita -->
    <topicref href="chapters/ch1.dita"/>     <!-- Works with relative paths -->
    <topicref href="overview.dita#intro"/>   <!-- Handles fragment IDs -->
</map>
```

### Publishing a Book

1. Create bookmap: `DITA: Create New Bookmap`
2. Create chapters: `DITA: Create New Topic` (multiple times)
3. Edit bookmap to reference chapters
4. Use **Ctrl+Click navigation** to quickly jump between bookmap and chapter files
5. Validate: `Ctrl+Shift+V`
6. Publish: `Ctrl+Shift+B` → Select format
7. Open output folder

### Previewing Changes

1. Open `.dita` file
2. Make edits
3. Press `Ctrl+Shift+H` to preview
4. Preview auto-refreshes on save
5. Toggle between source and preview

### Using Filters (DITAVAL)

```json
{
    "ditacraft.ditaOtArgs": [
        "--filter=filters/product-a.ditaval"
    ]
}
```

## Development

### Building from Source

```bash
# Clone repository
git clone https://github.com/jyjeanne/ditacraft.git
cd ditacraft

# Install dependencies
npm install

# Compile TypeScript
npm run compile

# Run tests
npm test

# Package extension
npm run package
```

### Project Structure

```
ditacraft/
├── src/                         # Client-side extension code
│   ├── extension.ts             # Entry point
│   ├── commands/                # Command handlers
│   ├── providers/               # Tree views, validation, link & decoration providers
│   ├── utils/                   # Utilities (DITA-OT, key space, map parser, rate limiter)
│   └── test/                    # Client test suites (683+ tests)
├── server/                      # LSP Language Server (separate process)
│   ├── src/
│   │   ├── server.ts            # Server entry point & capability registration
│   │   ├── serverHandlers.ts    # Extracted LSP handler wiring & capabilities
│   │   ├── features/            # LSP feature handlers
│   │   │   ├── validation.ts    # Diagnostics (XML, DITA structure, IDs)
│   │   │   ├── completion.ts    # IntelliSense completions
│   │   │   ├── hover.ts         # Hover documentation
│   │   │   ├── symbols.ts       # Document & workspace symbols
│   │   │   ├── definition.ts    # Go to definition
│   │   │   ├── references.ts    # Find references
│   │   │   ├── rename.ts        # Rename with reference updates
│   │   │   ├── formatting.ts    # XML formatting
│   │   │   ├── codeActions.ts   # Quick fixes (12 actions)
│   │   │   ├── linkedEditing.ts # Tag name sync editing
│   │   │   ├── folding.ts       # Folding ranges
│   │   │   ├── documentLinks.ts # Clickable links
│   │   │   ├── crossRefValidation.ts    # Cross-file reference + scope validation
│   │   │   ├── circularRefDetection.ts  # Circular reference detection (DFS)
│   │   │   ├── workspaceValidation.ts   # Cross-file duplicate IDs, unused topics
│   │   │   ├── ditaRulesValidator.ts    # 43 Schematron-equivalent DITA rules (incl. DITA 2.0)
│   │   │   ├── profilingValidation.ts   # Subject scheme controlled values
│   │   │   └── customRulesValidator.ts  # User-defined regex validation rules
│   │   ├── services/            # Domain services with caching
│   │   │   ├── validationPipeline.ts       # 13-phase orchestration
│   │   │   ├── suppressionEngine.ts        # Comment-based rule suppression
│   │   │   ├── interfaces.ts               # Service interfaces (IKeySpaceService, etc.)
│   │   │   ├── catalogValidationService.ts # DTD validation (TypesXML)
│   │   │   ├── rngValidationService.ts     # RNG validation (salve-annos)
│   │   │   ├── keySpaceService.ts          # Key space resolution + caching
│   │   │   └── subjectSchemeService.ts     # Subject scheme parsing
│   │   ├── utils/               # Server utilities
│   │   │   ├── types.ts                    # Shared types (DitaVersion, RuleCategory)
│   │   │   ├── diagnosticCodes.ts          # Central diagnostic code registry (78 codes)
│   │   │   ├── textUtils.ts               # Comment stripping, offsetToRange, offsetToPosition
│   │   │   ├── xmlTokenizer.ts            # Error-tolerant state-machine tokenizer
│   │   │   ├── i18n.ts                    # Localization (80+ messages EN+FR)
│   │   │   └── ...
│   │   ├── messages/            # Localization bundles (en.json, fr.json — 80+ message keys)
│   │   └── data/                # DITA schema & specialization data (@class matching)
│   └── test/                    # Server test suites (881+ tests)
├── mcp/                         # Standalone MCP server (Model Context Protocol)
│   ├── src/
│   │   └── server.ts            # MCP entry point (6 tools, 3 resources)
│   └── test/                    # MCP test suites + smoke tests
├── dist/                        # Standalone bundles (built by npm run build-standalone)
│   ├── mcp-server.js            # Self-contained MCP server (3.2 MB)
│   └── lsp-server.js            # Self-contained LSP server (2.0 MB)
├── dtds/                        # DITA 1.2, 1.3, and 2.0 DTD files (master catalog)
├── docs/                        # Documentation
│   ├── architecture.puml        # Architecture diagram (PlantUML)
│   └── user-guide/              # DITA user guide (~80 files, bookmap structure)
├── ARCHITECTURE.md
├── DITA_LSP_ARCHITECTURE.md     # LSP server architecture documentation
├── ROADMAP.md
├── TEST_PLAN.md                 # LSP feature test plan
└── CHANGELOG.md
```

### Quality & Testing

DitaCraft includes comprehensive test coverage across client and server:

**Client Tests (683+ tests):**
- DTD validation, real-time validation, command & auto-detection
- Link navigation with key resolution, key space building & caching
- Security (path traversal, XXE protection), rate limiting
- Preview, file creation, configuration integration
- Activity bar views: DITA Explorer, Key Space, Diagnostics, file decorations
- Map hierarchy parser (25 tests)

**LSP Server Tests (881+ tests):**
- Reference parser (40 tests) - all 6 exported parsing functions
- XML tokenizer (26 tests) - state machine, error recovery, CRLF, context detection, Unicode/CJK
- XML formatting (25 tests) - indentation, inline, preformatted, edge cases, range formatting
- Folding ranges (10 tests) - elements, comments, CDATA, CRLF
- Workspace scanner (8 tests) - offset-to-position conversion
- Validation diagnostics (30 tests) - XML, DITA structure, IDs, maps, DITAVAL
- Completions (19 tests) - element, attribute, value, DITAVAL, subject scheme completions
- Hover (17 tests) - documentation, fallback, non-tag, DITAVAL, conref preview
- Document symbols (13 tests) - outline, titles, maps, self-closing
- Workspace symbols (8 tests) - cross-file search, in-memory preference
- Code actions (19 tests) - all 12 quick fixes + edge cases
- Linked editing (15 tests) - tag pairing, nesting, boundaries
- Cross-reference validation - href, conref, keyref target validation
- DITA rules validator - 43 Schematron-equivalent rules (5 categories incl. DITA 2.0) + 25 DITA 2.0 tests
- Custom rules validator - 23 tests (regex matching, fileTypes, caching, severity mapping, ReDoS protection)
- Profiling validation - subject scheme controlled value checks
- Validation pipeline - severity overrides, comment-based suppression, large file optimization, pipeline budget
- Subject scheme service - parsing, caching, hierarchy, value constraints
- DITA specialization - @class matching, topic/map type names, utility functions
- DITA version detector - version detection from content (1.0-2.0)
- Key space service - 100+ tests: keyref chains, keyscope nesting/inheritance/inline branches, provenance, scope explosion cap, explainKey reporting
- Server handlers - 31 wiring tests + 19 settings tests
- Edge cases - empty files, long lines, mixed CRLF, Unicode/CJK content

**MCP Server Tests (standalone Mocha):**
- Tool tests: `dita_validate`, `dita_context_snapshot`, `dita_key_space`, `dita_map_structure`, `dita_resolve_reference`, `dita_explain_key`
- Resource tests: all 3 workspace resources
- Security tests: path traversal rejection, workspace isolation
- Smoke test: `npx tsx mcp/test/smoke-test.ts` (end-to-end tools + resources)

**Running Tests:**
```bash
# Run client tests (requires VS Code)
npm test

# Run server tests (standalone, no VS Code needed)
cd server && npm test

# Run a single server test suite
cd server && npm test -- --grep "KeySpaceService"

# Run MCP server tests (standalone, no VS Code needed)
cd mcp && npx tsc -p test/tsconfig.json && npx mocha out/test/mcp/test/*.test.js --ui tdd --timeout 30000

# MCP smoke test (validates tools + resources end-to-end)
npx tsx mcp/test/smoke-test.ts

# Compile everything
npm run compile
```

## Known Limitations

### Smart Navigation

The current implementation provides comprehensive navigation support. Remaining minor limitations:

1. **Same-file Content References (`@conref` with `#`)** - e.g., `<ph conref="#v4.3/summary"/>`
   - References starting with `#` point to elements within the same file
   - Currently opens the file but doesn't scroll to the specific element

2. **Conditional Key Definitions**
   - Keys with DITAVAL conditions may not be resolved correctly
   - The key space builder uses the first definition found (no condition evaluation)

**What works:**
- ✅ `href="path/to/file.dita"` — Direct file paths with or without fragment identifiers
- ✅ `conref="file.dita#element_id"` — Content references
- ✅ `keyref="key-name"` — Key references with full key space resolution
- ✅ `conkeyref="key-name/element"` — Content key references
- ✅ Keyref chains (multi-hop) across nested key scopes
- ✅ `@keyscope` nesting, inheritance, inline scope branches (DITA 1.3 spec-compliant)
- ✅ Scope explosion protection (50,000-key cap)
- ✅ Automatic root map discovery and tiered caching

### Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Add tests for new features
5. Ensure all tests pass (`npm test`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

## Troubleshooting

### DITA-OT Not Found

**Problem:** Extension shows "DITA-OT not found"

**Solution:**
1. Verify DITA-OT is installed
2. Run "DITA: Configure DITA-OT Path" command
3. Select DITA-OT installation directory
4. Verify with "DITA: Validate Current File"

### Validation Errors

**Problem:** Validation shows unexpected errors

**Solution:**
1. Check XML syntax (closing tags, quotes, etc.)
2. Verify DOCTYPE declaration
3. Try switching validation engine: `"ditacraft.validationEngine": "built-in"`

### Publishing Fails

**Problem:** Publishing fails with error

**Solution:**
1. Check DITA-OT logs in Output panel
2. Verify output directory is writable
3. Check for syntax errors in DITA file
4. Try publishing with `--verbose` flag:
   ```json
   "ditacraft.ditaOtArgs": ["--verbose"]
   ```

### Smart Navigation Not Working

**Problem:** Ctrl+Click on href attributes doesn't open files

**Solution:**
1. Verify you're in a `.ditamap` or `.bookmap` file (check file extension in status bar)
2. Hover over the href value - it should be underlined if detected as a link
3. Make sure you're clicking on the href value itself (e.g., `introduction.dita`), not the attribute name `href=`
4. Check that the referenced file path is correct and file exists
5. Try reloading VS Code window (`Ctrl+R` / `Cmd+R` in VS Code)
6. Verify extension is activated (look for "DitaCraft" in Extensions)

**Example of correct usage:**
```xml
<topicref href="introduction.dita"/>
              ^^^^^^^^^^^^^^^^^^^^
         Ctrl+Click here (on the value)
```

### Preview Not Showing

**Problem:** Preview panel is blank or shows error

**Solution:**
1. Verify HTML5 output was generated
2. Check output directory exists
3. Look for JavaScript errors in Developer Tools
4. Try republishing: `Ctrl+Shift+B` → HTML5

## Documentation

DitaCraft includes comprehensive documentation written in DITA format:

### 📖 User Guide (`docs/user-guide/`)

A complete DITA bookmap with ~80 files covering:

| Section | Contents |
|---------|----------|
| **Part I: Getting Started** | Introduction, Installation & Setup |
| **Part II: Using DitaCraft** | Commands (validation, publishing, file creation, navigation, guide validation), Features (smart navigation, validation, preview, map visualizer, key resolution) |
| **Part III: Configuration** | Settings (general, validation, publishing, preview) |
| **Appendix** | Keyboard Shortcuts reference |
| **Backmatter** | Glossary (40 terms), Index |

The user guide demonstrates DitaCraft's own capabilities - you can open it in VS Code to test validation, navigation, preview, and publishing features.

## Resources

### DITA Resources
- [DITA-OT Documentation](https://www.dita-ot.org/dev/)
- [OASIS DITA Specification](https://www.oasis-open.org/committees/dita/)
- [DITA Style Guide](http://www.ditastyle.com/)

### VS Code Resources
- [VS Code Extension API](https://code.visualstudio.com/api)
- [VS Code Publishing](https://code.visualstudio.com/api/working-with-extensions/publishing-extension)

## Recent Updates

### Version 0.9.0 (Current)
**Refactoring Tools, Templates & Scaffolding, Productivity Features, Publishing Enhancements**

The full [v0.9.0 implementation plan](docs/V0.9-IMPLEMENTATION-PLAN.md) — every prioritized item shipped, plus two of three Backlog items taken on as natural follow-ons (only Import from Markdown/HTML deferred, as the one item genuinely needing a design spike first).

**Added — Refactoring Tools:**
- **Rename key across all usages** — safely renames a `keys="..."` value and every `keyref`/`conkeyref` pointing at it, workspace-wide, with `conkeyref` matches verified against the key space (not just element-ID text) before rewriting
- **Move topic with reference updates** — moving/renaming a `.dita`/`.ditamap`/`.bookmap` file in the Explorer rewrites every inbound `href`/`conref` that pointed at its old path
- **Extract topic from section** — select a `<section>`, extract it into a new standalone topic (type inferred from the source topic), and replace it with an `xref`
- **Inline conref** — resolve a `conref`/`conkeyref` reference and splice the target content in place, stripping the reference attribute; strips nested descendant ids to avoid duplicate-id violations

**Added — Templates & Scaffolding:**
- **Custom topic templates** and a **project initialization wizard** — scaffold a new DITA project (maps, topics, `.ditaval`) from configurable templates

**Added — Productivity Features:**
- **Publishing profiles** — save/reuse transtype + output-dir + DITAVAL + extra-args combinations, remembers the last-used profile
- **Image insertion** and **table insertion** (CALS/simple) helpers with `<fig>` wrapper generation
- **Multi-file DITA-aware find & replace** and **batch metadata update** (profiling attributes across multiple selected files), both previewed via VS Code's native refactor-preview UI before applying
- **Visual DITAVAL condition editor** plus **live preview with conditions applied** and **condition highlighting** in the editor
- **Watch mode** (`DITA: Start/Stop Watch Mode`) — re-runs a full publish automatically whenever a watched DITA file changes, with quiet status-bar-only feedback (not incremental — DITA-OT has no first-class incremental build mode)

**Added — Knowledge Tooling:**
- **OKF Knowledge Base (okf-rs)** — `npm run okf` publishes a `git diff`-able, per-concept Open Knowledge Format bundle to `docs/okf-knowledge/`, complementing graphify's `docs/graph/graph.json`; adds change-impact analysis, a PR-review report generator, and call-cycle detection graphify doesn't have. See "OKF Knowledge Base (okf-rs)" in `CLAUDE.md`.

**Fixed (found via a deep code-review pass using both knowledge graphs):**
- Client-side `KeySpaceResolver` had zero DITA 1.3 `@keyscope` (nested/scoped key) support, unlike the server's `KeySpaceService` — a keyref inside a scoped branch could resolve to a *different file* via a clickable document link than via LSP-backed Go to Definition on the exact same reference. Ported the server's scope-prefix BFS, PushDown inheritance, inline scope blocks, and deferred peer-map resolution into the client resolver.
- `hover.ts`'s conref/conkeyref content preview carried its own buggy copy of an element-span algorithm (missing self-closing-element check, no comment-stripping) that could leak unrelated document content into the preview; now delegates to the already-hardened shared helper.

**2183+ Total Tests** — Client (966) + Server (1134) + MCP (83)

### Version 0.8.2
**Security Hardening, Key Space & Validation Race Fixes, Knowledge Graph**

**Added:**
- **Knowledge Graph (graphify)** — `npm run graph` generates a queryable codebase graph (`docs/graph/graph.json`, `GRAPH_REPORT.md`, `graph.svg`, interactive studio viewer, `flows.json`) via local tree-sitter AST extraction — no LLM/API keys. Auto-regenerates in `npm run watch` and on every push to `main`.

**Fixed — Security / path traversal:**
- Shared `isPathWithinWorkspace()` guard applied consistently across hover, completion, definition, cross-reference validation, circular-reference detection, document links, and the MCP context-graph handler
- Documents opened outside every workspace folder no longer misapply workspace-boundary checks to same-directory sibling references

**Fixed — Key space / cross-file references:**
- Diamond-shaped `@keyscope` map graphs no longer lose keys from re-visited submaps
- Windows case-mismatch in key-space path comparisons resolved (could silently miss key lookups/cache invalidation)
- Rename and Find All References now verify `conkeyref` matches resolve to the target file via the key space before rewriting/reporting, instead of matching on element-ID text alone
- Cross-file reference/rename `resolveKey` calls now run in parallel

**Fixed — Validation pipeline races and caching:**
- Timed-out/cancelled async validation phases no longer cache their empty fallback as a valid result (could mask broken links up to 5 minutes)
- Cancellation/budget-exceeded exits now still apply severity overrides, comment suppression, and the diagnostics cap
- Profiling validation now uses an immutable per-document subject-scheme snapshot instead of shared cross-document state
- AI Quick Fix now checks document version/closed state before applying an edit, preventing stale-edit application after a slow LLM call
- Settings cache no longer permanently poisoned by a single transient configuration-fetch failure
- Saving a `.dita` topic now correctly invalidates cross-reference diagnostics cached in other open documents

**Fixed — Editing / navigation:**
- Consolidated a recurring mismatched-closing-tag stack-desync bug (found across content model validation, symbols, folding, completion) into a shared `resyncStackToMatch()` helper
- DITA-SCH-011 quick fix no longer rewrites the wrong `<image>` element
- `body`/`conbody`/`section` content models now accept `parml`, `screen`, `syntaxdiagram`
- DITA-OT progress percentages no longer misapplied as cumulative increments

**Dependencies:** `@anthropic-ai/sdk` → 0.112.4, `vscode-languageclient` → 10.0.1, `fast-xml-parser` → 5.10.1, `typesxml` → 2.2.1, `c8` → 12.0.0, plus dev-dependency and `actions/setup-node` bumps

**1770+ Total Tests** — Client (710) + Server (977) + MCP (83)

### Version 0.8.1
**Preview Auto-Refresh Fix & Build Tooling**
- **Preview auto-refresh on save** (#96) — `ditacraft.previewAutoRefresh` now actually re-renders the preview when the previewed source file is saved (debounced 500ms, serialized refreshes, focus-preserving)
- **CommonJS test build fix** — resolved a `MODULE_TYPELESS_PACKAGE_JSON` failure in the test runner
- **vscode-languageclient 10 resolution fix** — corrected `moduleResolution` for the new `exports`-based package layout
- **Minimum VS Code version raised to 1.125.0** to match the bumped `@types/vscode`, restoring `vsce package`
- **Dependencies** — `vscode-languageclient` 9.0.1 → 10.0.0, `@vscode/test-electron` 2.5.2 → 3.0.0, `@types/node` 25.9.3 → 26.0.0, `actions/checkout` 6 → 7

### Version 0.8.0
**MCP Server, Standalone LSP Server & Standalone Bundles**

**MCP Server (`mcp/`):**
- **Standalone MCP server** — `dist/mcp-server.js` (3.2 MB, no `node_modules` needed); exposes DitaCraft's DITA intelligence to any MCP-aware AI agent (opencode, Claude Desktop, Cursor, Continue)
- **6 MCP tools** — `dita_validate`, `dita_context_snapshot`, `dita_key_space`, `dita_map_structure`, `dita_resolve_reference`, `dita_explain_key`
- **3 MCP resources** — `dita://workspace/maps`, `dita://workspace/diagnostics`, `dita://workspace/keys`
- **Workspace isolation** — Path traversal protection, HTTP/UNC/null-byte rejection; all communication stays local via stdio transport
- **Smoke test** — `npx tsx mcp/test/smoke-test.ts` validates all tools and resources end-to-end

**Standalone LSP Server (`dist/lsp-server.js`):**
- Self-contained bundle (2.0 MB); no `node_modules` needed at runtime
- Launch via `node dist/lsp-server.js --stdio`; embed via `child_process.spawn` in any Node.js LSP client
- Set `DITACRAFT_EXTENSION_ROOT` to point to the directory containing `dtds/`

**Build Commands:**
- `npm run build-standalone` — produces both `dist/mcp-server.js` and `dist/lsp-server.js`
- `npm run package` — produces the VS Code extension `.vsix` file

**Testing:**
- MCP server tests: `cd mcp && npx tsc -p test/tsconfig.json && npx mocha out/test/mcp/test/*.test.js --ui tdd --timeout 30000`
- LSP standalone smoke test: `npx tsx mcp/test/lsp-smoke-test.ts`

**1564+ Total Tests** — Client (683) + Server (881)

---

### Version 0.7.4
**AI Integration — GitHub Copilot, Anthropic, OpenAI & Ollama**

**AI Infrastructure:**
- **LLMRouterService** — Provider cascade with automatic fallback: Copilot (`vscode.lm`) → Anthropic → OpenAI → Ollama; `auto`, `copilot-only`, `byok-only`, `local-only` modes
- **CircuitBreaker** — Per-provider resilience: 3 failures in 5 min opens the breaker (10 min cooldown); AbortError (cancellations) never counted as failures
- **MetricsCollector** — Rolling buffer (1000 entries) tracking request count, latency, and error rate per provider
- **SecretManager** — API keys stored via `vscode.SecretStorage` (OS keychain); no plaintext settings

**AI Features:**
- **@ditacraft Chat Participant** — 4 slash commands: `/restructure`, `/validate`, `/explain`, `/suggest-reuse`
- **F2: AI Map Restructure** — AI proposes restructured map hierarchy; diff view with user confirmation before writing
- **F3: AI Quick Fix** — Code Actions "Fix with AI" for 12 diagnostic codes (CM-001/002/003, XREF-001/003/004, STRUCT-003/004/005/008, DTD-001, XML-001)
- **F4: AI Completion** — AI-enriched IntelliSense for element content and attribute values
- **Configure AI WebView** — Guided setup for provider selection, API keys, feature toggles, and live metrics

**LSP Additions:**
- `dita/getContextGraph`, `dita/validateFragment`, `dita/buildContextSnapshot` (Levels 1/2/3 sliding window)

**1537+ Total Tests** — Client (642) + Server (895)

### Version 0.7.3
**Key Space Algorithm Completion, Validation Pipeline Hardening, TypeScript 6.0 & TypesXML 2.0**

**Key Space (7-gap improvement plan complete):**
- **Keyref Chains** — Multi-hop keyref resolution across scopes; chain scope prefix bug fixed so chains inside scoped peer maps resolve correctly
- **Keyscope Inheritance & Inline Branches** — PushDown scope inheritance and `@keyscope` on non-map topicrefs treated as anonymo

More