# Outline Import Script - Ralph Loop Prompt ## Your Mission Build `import_to_outline.sh` and `outline_import.py` - companion scripts to the existing export tools that import markdown files back into Outline wiki. **Requirements Document:** Read `IMPORT_SCRIPT.MD` for full specifications. **Reference Implementation:** Study `export_with_trees.sh` and `outline_export_fixed.py` for patterns. --- ## Iteration Protocol Each iteration, follow this cycle: ### 1. Assess Current State ```bash # Check what exists ls -la *.sh *.py 2>/dev/null git status git log --oneline -5 2>/dev/null || echo "No git history" ``` ### 2. Read Requirements (if needed) - Review `IMPORT_SCRIPT.MD` for specifications - Review `outline_export_fixed.py` for API patterns and settings.json structure - Review `settings.json` for configuration format ### 3. Implement Next Phase Work on the current phase until complete, then move to the next. ### 4. Test Your Work - Run syntax checks: `python3 -m py_compile outline_import.py` - Run bash checks: `bash -n import_to_outline.sh` - Test `--help` output - Test `--dry-run` mode against `outline_export/` directory ### 5. Commit Progress ```bash git add -A && git commit -m "Phase X: description" ``` --- ## Implementation Phases ### Phase 1: Core Python Structure Create `outline_import.py` with: - [ ] `OutlineImporter` class with settings loading (copy pattern from `outline_export_fixed.py`) - [ ] API helper methods: `_api_request()`, `_get_collections()`, `_create_collection()` - [ ] Argument parsing with all CLI options from spec - [ ] Basic logging setup **Verification:** `python3 -m py_compile outline_import.py` passes ### Phase 2: Metadata Loading - [ ] Load `_collection_metadata.json` from each collection directory - [ ] Build document tree from `documents` array - [ ] Implement topological sort for parent-before-child ordering - [ ] Handle missing/invalid metadata gracefully **Verification:** Can parse metadata from `outline_export/*/` ### Phase 3: Collection Import Logic - [ ] Check if collection exists via `/api/collections.list` - [ ] Create collection via `/api/collections.create` - [ ] Handle `--force` mode (delete and recreate) - [ ] Skip existing collections by default **Verification:** `--dry-run` shows correct collection operations ### Phase 4: Document Import with Hierarchy - [ ] Read markdown content from files - [ ] Create documents via `/api/documents.create` - [ ] Maintain ID mapping: `old_id -> new_id` - [ ] Set `parentDocumentId` using mapped IDs - [ ] Handle missing parent (create as root-level) **Verification:** `--dry-run` shows correct document hierarchy ### Phase 5: Single Collection Mode - [ ] Implement `--single` flag - [ ] Create timestamped collection name `import_YYYYMMDD_HHMMSS` - [ ] Convert original collection folders to parent documents - [ ] Preserve nested hierarchy under these parents **Verification:** `--dry-run --single` shows consolidated structure ### Phase 6: Progress Visualization - [ ] Tree-style output matching spec (├──, └──, │) - [ ] Status indicators (✓ created, ✗ error, ○ skipped) - [ ] Summary statistics (collections/documents created/skipped/errors) - [ ] Duration tracking **Verification:** Output matches examples in IMPORT_SCRIPT.MD Section 7 ### Phase 7: Bash Wrapper Script Create `import_to_outline.sh` with: - [ ] Docker execution (matching `export_with_trees.sh` pattern) - [ ] CLI argument passthrough - [ ] Help text - [ ] Pre-flight checks (settings.json exists, source directory exists) **Verification:** `./import_to_outline.sh --help` works ### Phase 8: Error Handling & Polish - [ ] Retry logic for API failures (3 attempts, exponential backoff) - [ ] Proper error messages for all failure modes - [ ] Rate limiting delay between API calls - [ ] Verbose/debug output levels **Verification:** All error scenarios from spec handled --- ## Success Criteria All of the following must be true: 1. **Files exist:** `import_to_outline.sh` and `outline_import.py` 2. **Syntax valid:** Both pass syntax checks without errors 3. **Help works:** `./import_to_outline.sh --help` shows usage 4. **Dry-run works:** `./import_to_outline.sh --dry-run` parses `outline_export/` and shows planned operations 5. **Single mode:** `./import_to_outline.sh --dry-run --single` shows consolidated import plan 6. **Matches spec:** Output format matches IMPORT_SCRIPT.MD Section 7 examples --- ## Completion Signal When ALL success criteria are met, output: ``` IMPORT SCRIPT COMPLETE ``` **Do not output this promise until:** - Both files exist and pass syntax checks - `--help` displays properly - `--dry-run` successfully parses metadata and shows planned operations - Output format matches the specification --- ## Anti-Patterns to Avoid 1. **Don't skip phases** - Complete each phase before moving on 2. **Don't forget commits** - Commit after each successful phase 3. **Don't ignore errors** - Fix syntax/import errors before proceeding 4. **Don't deviate from spec** - Follow IMPORT_SCRIPT.MD precisely 5. **Don't over-engineer** - Implement exactly what's specified, no more --- ## Helpful Context ### API Endpoint Examples (from spec) ```python # Create collection POST /api/collections.create {"name": "Bewerbungen", "permission": "read_write"} # Create document POST /api/documents.create { "collectionId": "col-uuid", "title": "Document Title", "text": "# Content\n\nMarkdown here...", "parentDocumentId": "parent-uuid-or-null", "publish": true } ``` ### Docker Execution Pattern ```bash docker run --rm --network domnet \ --user "$(id -u):$(id -g)" \ -e HOME=/tmp \ -v "$WORK_DIR:/work" \ -w /work \ python:3.11-slim \ bash -c "pip install -qqq requests 2>/dev/null && python3 outline_import.py $CLI_ARGS" ``` ### Settings Structure (existing in settings.json) ```json { "source": { "url": "http://outline:3000", "token": "ol_api_xxx" } } ``` --- ## Current Iteration Read the files, check git history, determine which phase you're on, and continue from there. If starting fresh: Begin with Phase 1.