- export_with_trees.sh: Bash wrapper for Outline export - outline_export_fixed.py: Python export implementation - IMPORT_SCRIPT.MD: PRD for import script (to be built) - RALPH_PROMPT.md: Ralph Loop prompt for building import script - CLAUDE.md: Project documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.0 KiB
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
# 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.MDfor specifications - Review
outline_export_fixed.pyfor API patterns and settings.json structure - Review
settings.jsonfor 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
--helpoutput - Test
--dry-runmode againstoutline_export/directory
5. Commit Progress
git add -A && git commit -m "Phase X: description"
Implementation Phases
Phase 1: Core Python Structure
Create outline_import.py with:
OutlineImporterclass with settings loading (copy pattern fromoutline_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.jsonfrom each collection directory - Build document tree from
documentsarray - 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
--forcemode (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
parentDocumentIdusing mapped IDs - Handle missing parent (create as root-level)
Verification: --dry-run shows correct document hierarchy
Phase 5: Single Collection Mode
- Implement
--singleflag - 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.shpattern) - 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:
- Files exist:
import_to_outline.shandoutline_import.py - Syntax valid: Both pass syntax checks without errors
- Help works:
./import_to_outline.sh --helpshows usage - Dry-run works:
./import_to_outline.sh --dry-runparsesoutline_export/and shows planned operations - Single mode:
./import_to_outline.sh --dry-run --singleshows consolidated import plan - Matches spec: Output format matches IMPORT_SCRIPT.MD Section 7 examples
Completion Signal
When ALL success criteria are met, output:
<promise>IMPORT SCRIPT COMPLETE</promise>
Do not output this promise until:
- Both files exist and pass syntax checks
--helpdisplays properly--dry-runsuccessfully parses metadata and shows planned operations- Output format matches the specification
Anti-Patterns to Avoid
- Don't skip phases - Complete each phase before moving on
- Don't forget commits - Commit after each successful phase
- Don't ignore errors - Fix syntax/import errors before proceeding
- Don't deviate from spec - Follow IMPORT_SCRIPT.MD precisely
- Don't over-engineer - Implement exactly what's specified, no more
Helpful Context
API Endpoint Examples (from spec)
# 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
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)
{
"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.