Synchronize PROJECT_PLAN.md between local filesystem and PlanFlow cloud service with bidirectional push/pull operations
Synchronize PROJECT_PLAN.md between your local workspace and PlanFlow cloud service. This skill enables bidirectional syncing with conflict detection and resolution.
PlanFlow Sync manages synchronization of your project plan file between local and cloud environments. It supports push operations (local to cloud), pull operations (cloud to local), status checks to compare versions, and handles conflicts with optional force flags.
Before using this skill, ensure:
```bash
/pfSync # Show sync status (default)
/pfSync push # Push local → cloud
/pfSync push --force # Overwrite cloud without confirmation
/pfSync pull # Pull cloud → local
/pfSync pull --force # Overwrite local without confirmation
```
Read configuration from both local project config and global user config. Local settings override global ones.
```javascript
const localConfigPath = "./.plan-config.json"
const globalConfigPath = "~/.config/claude/plan-plugin-config.json"
// Parse both configs, merge with local taking precedence
// Extract: language, cloudConfig.apiToken, cloudConfig.projectId, cloudConfig.apiUrl
// Load appropriate localization file from locales/{language}.json
```
**Required config values:**
**Validation:**
```javascript
const args = commandArgs.trim().split(/\s+/)
const action = args[0] || "status" // Valid: status, push, pull
const forceFlag = args.includes("--force")
```
#### ACTION: status (default)
Display comparison between local and cloud versions:
1. Check if `PROJECT_PLAN.md` exists locally
2. Fetch cloud metadata via GET `{apiUrl}/projects/{projectId}/plan/metadata`
3. Compare modification timestamps
4. Show summary with:
- Local file modification time
- Cloud sync timestamp
- Sync status (local ahead, cloud ahead, or in sync)
- Brief change summary if available
- Suggested action (push or pull)
**Output format:**
```
📊 {t.commands.sync.status}
{t.commands.sync.localFile} PROJECT_PLAN.md (modified X time ago)
{t.commands.sync.cloudProject} {project name} (synced X time ago)
{t.commands.sync.syncStatus} {status message}
{t.commands.sync.changes}
• Change summary items
💡 Run: /pfSync {suggested action}
```
#### ACTION: push
Push local PROJECT_PLAN.md to cloud:
1. Verify `PROJECT_PLAN.md` exists locally (error if missing: `t.commands.sync.noPlan`)
2. Read file contents
3. Prepare JSON payload with plan content
4. Send PUT request to `{apiUrl}/projects/{projectId}/plan` with Authorization header
5. Update `lastSyncedAt` in local config file
6. Display success message with timestamp
**API Request:**
```bash
curl -s -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {apiToken}" \
-d '{"plan": "{file_contents}"}' \
"{apiUrl}/projects/{projectId}/plan"
```
**Success output:**
```
✅ {t.commands.sync.pushSuccess}
{t.commands.sync.uploaded} PROJECT_PLAN.md
{t.commands.sync.to} {project name}
{t.commands.sync.at} {timestamp}
```
#### ACTION: pull
Pull plan from cloud to local:
1. Fetch plan content via GET `{apiUrl}/projects/{projectId}/plan`
2. If `PROJECT_PLAN.md` exists locally and `--force` not provided:
- Compare local and cloud content
- Show diff summary
- Use `AskUserQuestion` to confirm overwrite
- Abort if user declines
3. Write cloud content to `PROJECT_PLAN.md`
4. Update `lastSyncedAt` in local config
5. Display success message with timestamp
**API Request:**
```bash
curl -s \
-H "Authorization: Bearer {apiToken}" \
"{apiUrl}/projects/{projectId}/plan"
```
**Conflict detection output:**
```
⚠️ {t.commands.sync.localChanges}
{t.commands.sync.diff}
- Local changes summary
+ Cloud changes summary
{t.commands.sync.confirmPull}
```
**Success output:**
```
✅ {t.commands.sync.pullSuccess}
{t.commands.sync.downloaded} PROJECT_PLAN.md
{t.commands.sync.from} {project name}
{t.commands.sync.at} {timestamp}
```
Handle these error scenarios gracefully:
**Not authenticated:**
```
❌ {t.commands.sync.notAuthenticated}
Run: /pfLogin
```
**Project not linked:**
```
❌ {t.commands.sync.notLinked}
Run: /pfCloud link
```
**No local plan file (push only):**
```
❌ {t.commands.sync.noPlan}
Run: /planNew to create a plan first.
```
**Network error:**
```
❌ Network error. Please check your connection.
```
**API errors:**
**Local project config** (`./.plan-config.json`):
```json
{
"language": "en",
"cloud": {
"apiToken": "...",
"projectId": "...",
"apiUrl": "https://api.planflow.tools",
"lastSyncedAt": "2024-01-15T14:30:00Z"
}
}
```
**Global user config** (`~/.config/claude/plan-plugin-config.json`): Same structure, used as fallback.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/planflow-sync/raw