Files
outline-sync/CLAUDE.md
Claude e4c69efd12 Add import tool documentation to CLAUDE.md
- Usage examples and CLI options
- Import modes (collection-per-folder, single)
- Import flow explanation
- Output example with tree visualization
- Duplicate handling and error handling reference

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 22:49:07 +01:00

7.6 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a tool for exporting Outline wiki data via API. The script runs inside a Docker container on the domnet network to bypass Authentik SSO authentication and access the internal Outline API directly (http://outline:3000).

Usage

# Run the export with tree visualization
./export_with_trees.sh

# Preview without exporting (dry run)
./export_with_trees.sh --dry-run

# Run with verbose output
./export_with_trees.sh -v

CLI Options

--dry-run, -n       Preview what would be exported without writing files
--output, -o DIR    Output directory (overrides settings.json)
--verbose, -v       Increase verbosity (-vv for debug)
--skip-verify       Skip post-export verification
--skip-health-check Skip pre-export health check
--settings FILE     Path to settings file (default: settings.json)

Running the Python Export Directly

docker run --rm --network domnet \
    -v "$(pwd):/work" \
    -w /work \
    python:3.11-slim \
    bash -c "pip install -q requests tqdm && python3 outline_export_fixed.py"

# With options
docker run --rm --network domnet \
    -v "$(pwd):/work" \
    -w /work \
    python:3.11-slim \
    bash -c "pip install -q requests tqdm && python3 outline_export_fixed.py --dry-run"

Architecture

Docker Network Integration

  • Script runs in Docker container attached to domnet bridge network
  • Direct API access to http://outline:3000 (internal) bypasses SSO
  • Uses python:3.11-slim image with requests and tqdm dependencies

Export Flow

  1. Fetch collections via /api/collections.list
  2. Get navigation tree via /api/collections.documents (source of truth for hierarchy)
  3. Fetch full document content via /api/documents.info (with caching)
  4. Export recursively maintaining parent-child structure
  5. Save metadata (_collection_metadata.json) per collection
  6. Generate manifest with checksums for verification

Key Files

  • export_with_trees.sh - Main export script with tree visualization
  • outline_export_fixed.py - Core export logic with OutlineExporter class
  • settings.json - API URL and token configuration (contains secrets)
  • outline_export/ - Output directory with markdown files and metadata
  • outline_backup_*.tar.gz - Timestamped compressed backups

Configuration

Settings are in settings.json:

  • source.url - Internal Docker URL (http://outline:3000)
  • source.token - Outline API token
  • export.output_directory - Output path (default: outline_export)
  • advanced.max_hierarchy_depth - Prevent infinite recursion (default: 100)

Important Notes

Security

  • settings.json contains API token - never commit to git
  • Backup files may contain sensitive wiki content

Backup System

  • Each export automatically backs up previous exports to outline_backup_YYYYMMDD_HHMMSS.tar.gz
  • Old uncompressed export directory is deleted after backup
  • Backups achieve 90%+ compression on markdown content

Reliability Features

  • Health check: Verifies API connectivity before export
  • Retry logic: Failed API requests retry up to 3 times with exponential backoff
  • Logging: Structured logging with configurable verbosity levels

Document Counting

The navigation tree (/api/collections.documents) is the source of truth for document hierarchy. Document counting is recursive to include all nested children.


Import Tool

The import script restores exported markdown files back into Outline, preserving the full document hierarchy.

Usage

# Import all collections from outline_export/
./import_to_outline.sh

# Preview what would be imported (no changes made)
./import_to_outline.sh --dry-run

# Import into a single timestamped collection
./import_to_outline.sh --single

# Import from a different directory
./import_to_outline.sh -d exports/

# Overwrite existing collections
./import_to_outline.sh --force

CLI Options

-s, --single        Import all into single timestamped collection
-n, --dry-run       Preview operations without making changes
-d, --source DIR    Source directory (default: outline_export)
-v, --verbose       Increase verbosity (-vv for debug)
-f, --force         Overwrite existing collections (instead of skip)
--settings FILE     Path to settings file (default: settings.json)
-h, --help          Show help message

Import Modes

Collection-per-Folder (Default) Each subdirectory becomes a separate collection:

outline_export/
├── Bewerbungen/     → Creates "Bewerbungen" collection
├── Projekte/        → Creates "Projekte" collection
└── Privat/          → Creates "Privat" collection

Single Collection (--single) All content goes into one timestamped collection:

outline_export/
├── Bewerbungen/     → Becomes parent doc "Bewerbungen"
├── Projekte/        → Becomes parent doc "Projekte"
└── Privat/          → Becomes parent doc "Privat"

All imported into: "import_20260119_143052" collection

Import Flow

  1. Load _collection_metadata.json from each collection directory
  2. Build document tree maintaining parent-child relationships
  3. Create collections via /api/collections.create
  4. Create documents via /api/documents.create with proper parentDocumentId
  5. Map old IDs to new IDs to maintain hierarchy
  6. Display tree-style progress with status indicators

Key Files

  • import_to_outline.sh - Bash wrapper with Docker execution
  • outline_import.py - Core import logic with OutlineImporter class

Output Example

════════════════════════════════════════════════════════════
  OUTLINE IMPORT
════════════════════════════════════════════════════════════

Source:  outline_export/
Target:  http://outline:3000
Mode:    Collection per folder

Checking API connectivity... ✓

Bewerbungen/ (11 documents)
  Creating collection... ✓ (id: 7f3a...)
  ├── CV.md                              ✓ created
  ├── Tipico.md                          ✓ created
  │   ├── Pitch Tipico.md                ✓ created
  │   └── Fragen 3. Runde.md             ✓ created
  └── Ihre PVS.md                        ✓ created

════════════════════════════════════════════════════════════
SUMMARY
════════════════════════════════════════════════════════════
  Collections:  1 created, 0 skipped, 0 errors
  Documents:   11 created, 0 skipped, 0 errors
  Duration:     2.3 seconds
════════════════════════════════════════════════════════════

Duplicate Handling

Scenario Default With --force
Collection exists Skip entire collection Delete and recreate
Document exists Skip document Update document

Error Handling

  • API connection failure: Abort with error message
  • Collection creation fails: Abort that collection, continue others
  • Document creation fails: Log error, continue with siblings
  • Missing markdown file: Log warning, skip document
  • Parent not found: Create as root-level document