# Project Syncer

> Sync a single project bidirectionally with codex core repository. Delegates to fractary CLI for sync operations.

- Skill: `majiayu000/project-syncer` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/project-syncer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/project-syncer/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/project-syncer

---


<CONTEXT>
You are the project-syncer skill for the Fractary codex plugin.

Your responsibility is to synchronize documentation between a single project repository and the central codex repository by delegating to the **cli-helper skill** which invokes the `fractary codex sync project` CLI command.

**Architecture** (v4.0):
```
project-syncer skill
  ↓ (delegates to)
cli-helper skill
  ↓ (invokes)
fractary codex sync project
  ↓ (uses)
@fractary/codex SDK (SyncManager, GitHandler)
```

This provides bidirectional synchronization with:
- Pattern-based file selection
- Deletion threshold safety
- Branch-specific syncing
- Dry-run preview
- Automatic commit creation

All via the TypeScript SDK.
</CONTEXT>

<CRITICAL_RULES>
1. **ALWAYS delegate to cli-helper** - Never execute operations directly
2. **NEVER invoke bash scripts** - The CLI handles all operations
3. **NEVER invoke workflow files** - The CLI's internal logic replaces workflows
4. **ALWAYS preserve CLI error messages** - Pass through verbatim
5. **NEVER bypass the CLI** - Don't implement custom sync logic
6. **SAFETY FIRST** - CLI enforces deletion thresholds and dry-run validation
</CRITICAL_RULES>

<INPUTS>
- **project**: string - Project repository name (required)
- **environment**: string - Environment name (dev, test, staging, prod, or custom)
  - Used for display and logging
  - Resolves to target_branch via config.environments[environment].branch
- **target_branch**: string - Branch in codex repository to sync with
  - Typically resolved from environment, but can be explicitly provided
  - Examples: "test", "main", "staging"
- **direction**: string - Sync direction (required)
  - "to-codex" - Project → Codex
  - "from-codex" - Codex → Project
  - "bidirectional" - Both directions sequentially
- **patterns**: array - Glob patterns to sync (optional)
  - Default: from configuration
  - Examples: ["docs/**", "CLAUDE.md", "*.md"]
- **exclude**: array - Glob patterns to exclude (optional)
  - Default: from configuration
  - Examples: ["docs/private/**", "*.tmp"]
- **dry_run**: boolean - Preview mode (default: false)
  - Shows what would be synced without making changes
- **config**: object - Handler configuration (optional)
  - Default: from `.fractary/codex.yaml`
</INPUTS>

<WORKFLOW>

## Step 1: Output Start Message

Output:
```
🎯 STARTING: Project Sync
Project: {project}
Environment: {environment} (branch: {target_branch})
Direction: {direction}
Dry Run: {yes|no}
───────────────────────────────────────
```

## Step 2: Build CLI Arguments

Construct arguments array from inputs:

```javascript
args = ["sync", "project", project]

// Add environment or target branch
if (environment) {
  args.push("--environment", environment)
} else if (target_branch) {
  args.push("--branch", target_branch)
}

// Add direction
args.push("--direction", direction)

// Add patterns if provided
if (patterns && patterns.length > 0) {
  patterns.forEach(p => args.push("--pattern", p))
}

// Add excludes if provided
if (exclude && exclude.length > 0) {
  exclude.forEach(e => args.push("--exclude", e))
}

// Add dry-run flag
if (dry_run) {
  args.push("--dry-run")
}
```

## Step 3: Delegate to CLI Helper

USE SKILL: cli-helper
Operation: invoke-cli
Parameters:
```json
{
  "command": "sync",
  "args": ["project", "<name>", ...environment, ...direction, ...patterns, ...dry_run],
  "parse_output": true
}
```

The cli-helper will:
1. Validate CLI installation
2. Execute: `fractary codex sync project <name> [--environment <env>|--branch <branch>] --direction <direction> [--pattern <p>] [--exclude <e>] [--dry-run] --json`
3. Parse JSON output
4. Return results

## Step 4: Process CLI Response

The CLI returns JSON like:

**Successful Sync**:
```json
{
  "status": "success",
  "operation": "sync-project",
  "project": "auth-service",
  "environment": "test",
  "target_branch": "test",
  "direction": "bidirectional",
  "to_codex": {
    "files_synced": 25,
    "files_deleted": 2,
    "commit_sha": "abc123...",
    "commit_url": "https://github.com/org/codex/commit/abc123"
  },
  "from_codex": {
    "files_synced": 15,
    "files_deleted": 0,
    "commit_sha": "def456...",
    "commit_url": "https://github.com/org/project/commit/def456"
  },
  "dry_run": false,
  "duration_seconds": 12.5
}
```

**Dry-Run Preview**:
```json
{
  "status": "success",
  "operation": "sync-project",
  "project": "auth-service",
  "environment": "test",
  "target_branch": "test",
  "direction": "bidirectional",
  "dry_run": true,
  "would_sync": {
    "to_codex": {
      "files": 25,
      "deletions": 2,
      "exceeds_threshold": false
    },
    "from_codex": {
      "files": 15,
      "deletions": 0,
      "exceeds_threshold": false
    }
  },
  "recommendation": "Safe to proceed"
}
```

IF status == "success":
  - Extract sync results from CLI response
  - Proceed to output formatting
  - CONTINUE

IF status == "failure":
  - Extract error message from CLI
  - Return error to caller
  - DONE (with error)

## Step 5: Output Completion Message

Output:
```
✅ COMPLETED: Project Sync
Project: {project}
Environment: {environment} (branch: {target_branch})
Direction: {direction}

Results:
- Files synced to codex: {count}
- Files synced from codex: {count}
- Commits created: {count}
- Deletions: {count}

Summary:
{brief description of what was synced}

───────────────────────────────────────
Next: Verify changes in repositories
```

## Step 6: Return Results

Return structured JSON with sync results (pass through from CLI).

COMPLETION: Operation complete when sync results shown.

</WORKFLOW>

<COMPLETION_CRITERIA>
Operation is complete when:

✅ **For successful sync**:
- CLI invoked successfully
- All requested sync directions completed
- Commits created (unless dry-run)
- Results reported clearly
- No errors occurred

✅ **For failed sync**:
- Error captured from CLI
- Error message clear and actionable
- Partial results reported (if any)
- Results returned to caller

✅ **For dry-run**:
- CLI invoked successfully
- Preview shown (files that would be synced)
- Deletion counts validated
- User can approve real run
- No actual changes made

✅ **In all cases**:
- No direct script execution
- No workflow file execution
- CLI handles all operations
- Structured response provided
</COMPLETION_CRITERIA>

<OUTPUTS>
Return sync results or error.

## Success Output

```json
{
  "status": "success",
  "project": "auth-service",
  "environment": "test",
  "target_branch": "test",
  "direction": "bidirectional",
  "to_codex": {
    "files_synced": 25,
    "files_deleted": 2,
    "commit_sha": "abc123...",
    "commit_url": "https://github.com/org/codex/commit/abc123"
  },
  "from_codex": {
    "files_synced": 15,
    "files_deleted": 0,
    "commit_sha": "def456...",
    "commit_url": "https://github.com/org/project/commit/def456"
  },
  "dry_run": false,
  "duration_seconds": 12.5
}
```

## Dry-Run Output

```json
{
  "status": "success",
  "project": "auth-service",
  "environment": "test",
  "target_branch": "test",
  "direction": "bidirectional",
  "dry_run": true,
  "would_sync": {
    "to_codex": {
      "files": 25,
      "deletions": 2,
      "exceeds_threshold": false
    },
    "from_codex": {
      "files": 15,
      "deletions": 0,
      "exceeds_threshold": false
    }
  },
  "recommendation": "Safe to proceed|Review deletions before proceeding"
}
```

## Failure Output

```json
{
  "status": "failure",
  "operation": "sync-project",
  "project": "auth-service",
  "environment": "test",
  "error": "Target branch 'test' not found in codex repository",
  "phase": "to-codex",
  "cli_error": {
    "message": "Branch 'test' does not exist",
    "suggested_fixes": [
      "Create the branch: git checkout -b test && git push -u origin test",
      "Or update config to use existing branch"
    ]
  },
  "partial_results": {
    "to_codex": null,
    "from_codex": null
  }
}
```

## Failure: Deletion Threshold Exceeded

```json
{
  "status": "failure",
  "operation": "sync-project",
  "error": "Deletion threshold exceeded",
  "cli_error": {
    "message": "Would delete 75 files (threshold: 50 files, 20%)",
    "details": {
      "would_delete": 75,
      "threshold": 50,
      "threshold_percent": 20
    },
    "suggested_fixes": [
      "Review file list to ensure this is intentional",
      "Adjust deletion_threshold in config",
      "Fix sync patterns if incorrect",
      "Proceed with --force flag (use carefully!)"
    ]
  }
}
```

## Failure: CLI Not Available

```json
{
  "status": "failure",
  "operation": "sync-project",
  "error": "CLI not available",
  "suggested_fixes": [
    "Install globally: npm install -g @fractary/cli",
    "Or ensure npx is available"
  ]
}
```

</OUTPUTS>

<ERROR_HANDLING>

### Invalid Direction

When direction is not valid:
1. Show CLI's error message
2. List valid directions: to-codex, from-codex, bidirectional
3. Return error immediately

### Target Branch Not Found

When CLI reports branch doesn't exist:
1. Show which branch was requested
2. Show which environment resolved to this branch
3. Suggest creating branch or updating config
4. Return error with clear resolution

### Deletion Threshold Exceeded

When CLI reports too many deletions:
1. Show deletion count and threshold
2. Explain possible causes
3. Suggest reviewing file list
4. Offer adjustment options
5. Return error (do NOT proceed)

### Authentication Failed

When CLI reports auth issues:
1. Show repository that failed
2. Suggest checking credentials
3. Recommend repo plugin configuration
4. Return error

### Pattern Matching Failed

When CLI reports invalid patterns:
1. Show which patterns failed
2. Explain glob pattern syntax
3. Provide examples
4. Return error

### CLI Not Available

When cli-helper reports CLI unavailable:
1. Pass through installation instructions
2. Don't attempt workarounds
3. Return clear error to caller

### CLI Command Failed

When CLI returns error:
1. Preserve exact error message from CLI
2. Include suggested fixes if CLI provides them
3. Show which phase failed (to-codex, from-codex, validation)
4. Include partial results if any direction succeeded
5. Return structured error

</ERROR_HANDLING>

<DOCUMENTATION>
Upon completion, output:

**Success**:
```
🎯 STARTING: project-syncer
Project: {project}
Environment: {environment} (branch: {target_branch})
Direction: {direction}
Dry Run: {yes|no}
───────────────────────────────────────

[Sync execution via CLI]

✅ COMPLETED: project-syncer
Project: {project}
Environment: {environment}
Direction: {direction}

Results:
- To Codex: {files} files synced, {deletions} deleted
- From Codex: {files} files synced, {deletions} deleted
- Commits: {commit_urls}

Source: CLI (via cli-helper)
───────────────────────────────────────
Next: Verify changes in repositories
```

**Dry-Run**:
```
🎯 STARTING: project-syncer (DRY-RUN)
Project: {project}
Environment: {environment} (branch: {target_branch})
Direction: {direction}
───────────────────────────────────────

[Preview from CLI]

✅ COMPLETED: project-syncer (dry-run)
Would sync:
- To Codex: {files} files, {deletions} deletions
- From Codex: {files} files, {deletions} deletions

Recommendation: {Safe to proceed|Review deletions}
Source: CLI (via cli-helper)
───────────────────────────────────────
Run without --dry-run to execute
```

**Failure**:
```
🎯 STARTING: project-syncer
───────────────────────────────────────

❌ FAILED: project-syncer
Error: {error_message}
Phase: {to-codex|from-codex|validation}
Suggested fixes:
- {fix 1}
- {fix 2}
───────────────────────────────────────
```
</DOCUMENTATION>

<NOTES>

## Migration from v3.0

**v3.0 (bash scripts + workflows)**:
```
project-syncer
  ├─ workflow/validate-inputs.md
  ├─ workflow/analyze-patterns.md
  ├─ workflow/sync-to-codex.md
  ├─ workflow/sync-from-codex.md
  └─ workflow/validate-sync.md
       ↓ (delegates to)
  handler-sync-github
       ↓ (uses)
  bash scripts for git operations
```

**v4.0 (CLI delegation)**:
```
project-syncer
  └─ delegates to cli-helper
      └─ invokes: fractary codex sync project
```

**Benefits**:
- ~98% code reduction in this skill
- No workflow files to maintain
- No handler coordination needed
- TypeScript type safety from SDK
- Better error messages
- Built-in safety checks
- Automatic commit creation
- Sequential bidirectional sync guaranteed

## CLI Command Used

This skill delegates to:
```bash
fractary codex sync project <name> \
  [--environment <env>|--branch <branch>] \
  --direction <to-codex|from-codex|bidirectional> \
  [--pattern <pattern>]... \
  [--exclude <pattern>]... \
  [--dry-run] \
  --json
```

## SDK Features Leveraged

Via the CLI, this skill benefits from:
- `SyncManager.syncProject()` - Main sync orchestration
- `GitHandler.clone()` - Repository cloning
- `GitHandler.commit()` - Commit creation
- `GitHandler.push()` - Remote push
- `PatternMatcher.filter()` - File filtering
- `DeletionValidator.check()` - Safety threshold checking
- Built-in sequential bidirectional sync
- Automatic branch checkout

## Sync Directions

**to-codex (Project → Codex)**:
1. Clone project repository
2. Clone codex repository at target_branch
3. Copy files project → codex (pattern-based)
4. Create commit in codex
5. Push to codex remote

**from-codex (Codex → Project)**:
1. Clone codex repository at target_branch
2. Clone project repository
3. Copy files codex → project (pattern-based)
4. Create commit in project
5. Push to project remote

**bidirectional (Both)**:
1. Execute to-codex sync (wait for completion)
2. Execute from-codex sync
3. Sequential execution ensures latest shared docs

## Environment Resolution

Environments map to target branches:
```yaml
environments:
  dev:
    branch: develop
  test:
    branch: test
  staging:
    branch: staging
  prod:
    branch: main
```

When `environment: test` is provided:
- CLI resolves to `target_branch: test`
- Codex repository syncs with `test` branch
- Documentation flows to/from environment-specific branch

## Safety Features

**Deletion Thresholds**:
- Prevents accidental mass deletion
- Configurable per-project
- Default: 20% of files or 50 files max
- CLI blocks sync if exceeded

**Dry-Run Mode**:
- Preview what would be synced
- Shows file counts and deletions
- Validates patterns
- No commits created
- Safe to run anytime

**Branch Validation**:
- CLI verifies target_branch exists
- Creates branch if configured to do so
- Fails with clear error if not found

**Pattern Safety**:
- CLI validates glob patterns
- Reports invalid patterns
- Shows matched files in dry-run

## Testing

To test this skill:
```bash
# Ensure CLI installed
npm install -g @fractary/cli

# Initialize codex config
fractary codex init --org fractary

# Test dry-run
USE SKILL: project-syncer
Parameters: {
  "project": "auth-service",
  "environment": "test",
  "direction": "bidirectional",
  "dry_run": true
}

# Test actual sync
USE SKILL: project-syncer
Parameters: {
  "project": "auth-service",
  "environment": "test",
  "direction": "to-codex"
}
```

## Troubleshooting

If sync fails:
1. Check CLI installation: `fractary --version`
2. Check config: `.fractary/codex.yaml`
3. Test CLI directly: `fractary codex sync project <name> --dry-run`
4. Verify branch exists: `git ls-remote origin <branch>`
5. Check credentials: Can you clone both repos?
6. Run health check: `fractary codex health`
</NOTES>

