Initial commit: Export tools and import script requirements
- 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>
This commit is contained in:
202
RALPH_PROMPT.md
Normal file
202
RALPH_PROMPT.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# 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:
|
||||
|
||||
```
|
||||
<promise>IMPORT SCRIPT COMPLETE</promise>
|
||||
```
|
||||
|
||||
**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.
|
||||
Reference in New Issue
Block a user