SkillsSynchronizer

Class
implements LoggerAwareInterface
uses LoggerAwareTrait
Final: Yes

Synchronizes Fast Forward skills into consumer repositories.

Description

This class manages the creation and maintenance of symlinks from a consumer repository to the skills packaged within the fast-forward/dev-tools dependency. It handles initial sync, idempotent re-runs, and cleanup of broken links.

Table of Contents

Interfaces

Properties

 : Filesystem
 : Finder

Methods

__construct()

Initializes the synchronizer with an optional filesystem instance.

 : mixed
synchronize()

Synchronizes skills from the package to the consumer repository.

 : SynchronizeResult
createNewLink()

Creates a new symlink pointing to the packaged skill.

 : void
isSymlink()

Checks if a path is a symbolic link.

 : bool
preserveExistingNonSymlink()

Handles an existing non-symlink item at the target path.

 : void
processExistingSymlink()

Evaluates an existing symlink and determines whether to preserve or repair it.

 : void
processSkillLink()

Routes a skill link to the appropriate handling method based on target state.

 : void
repairBrokenLink()

Removes a broken symlink and creates a fresh one pointing to the current source.

 : void
syncPackageSkills()

Iterates through all packaged skills and processes each one.

 : void
Properties

$filesystem

Private Read-only
private Filesystem $filesystem = new Filesystem()
Methods

__construct()

Public

Initializes the synchronizer with an optional filesystem instance.

public __construct([Filesystem|null  $filesystem = new Filesystem()][, Finder  $finder = new Finder()]) : mixed

Description

If no filesystem is provided, a default Filesystem instance is created.

Parameters
$filesystem : Filesystem|null = new Filesystem()

Description

Filesystem instance for file operations

$finder : Finder = new Finder()

Description

Finder instance for locating skill directories in the package

synchronize()

Public

Synchronizes skills from the package to the consumer repository.

public synchronize( string  $skillsDir, string  $packageSkillsPath) : SynchronizeResult

Description

Ensures the consumer repository contains linked Fast Forward skills by creating symlinks to the packaged skills directory. Creates the target directory if missing, skips existing valid links, and repairs broken ones.

Parameters
$skillsDir : string

Description

Absolute path to the consumer's .agents/skills directory

$packageSkillsPath : string

Description

Absolute path to the packaged skills in the dependency

Return values

Description

Result containing counts of created, preserved, and removed links

Private

Creates a new symlink pointing to the packaged skill.

private createNewLink( string  $skillName, string  $targetLink, string  $sourcePath, SynchronizeResult  $result) : void

Description

This method is called when no existing item exists at the target path. Creates the symlink, logs the creation, and records it in the result.

Parameters
$skillName : string

Description

Name identifying the skill

$targetLink : string

Description

Absolute path where the symlink will be created

$sourcePath : string

Description

Absolute path to the packaged skill directory

$result : SynchronizeResult

Description

Result object for tracking creation

Private

Checks if a path is a symbolic link.

private isSymlink( string  $path) : bool
Parameters
$path : string
Return values
bool
Private

Handles an existing non-symlink item at the target path.

private preserveExistingNonSymlink( string  $skillName, SynchronizeResult  $result) : void

Description

When the target exists but is a real directory (not a symlink), this method preserves it unchanged and logs the decision. Real directories are not replaced to avoid accidental data loss.

Parameters
$skillName : string

Description

Name of the skill with the conflicting item

$result : SynchronizeResult

Description

Result tracker for preserved items

Private

Evaluates an existing symlink and determines whether to preserve or repair it.

private processExistingSymlink( string  $skillName, string  $targetLink, string  $sourcePath, SynchronizeResult  $result) : void

Description

Reads the symlink target and checks if it points to a valid, existing path. Delegates to repair if broken, otherwise preserves the valid link in place.

Parameters
$skillName : string

Description

Name of the skill with the existing symlink

$targetLink : string

Description

Absolute path to the existing symlink

$sourcePath : string

Description

Absolute path to the expected source directory

$result : SynchronizeResult

Description

Result tracker for preserved or removed links

Private

Routes a skill link to the appropriate handling method based on target state.

private processSkillLink( string  $skillName, string  $targetLink, string  $sourcePath, SynchronizeResult  $result) : void

Description

Determines whether the target path needs creation, preservation, or repair based on filesystem checks, then delegates to the corresponding method.

Parameters
$skillName : string

Description

Name of the skill being processed

$targetLink : string

Description

Absolute path where the symlink should exist

$sourcePath : string

Description

Absolute path to the packaged skill directory

$result : SynchronizeResult

Description

Result tracker for reporting outcomes

Private

Removes a broken symlink and creates a fresh one pointing to the current source.

private repairBrokenLink( string  $skillName, string  $targetLink, string  $sourcePath, SynchronizeResult  $result) : void

Description

Called when the existing symlink target either does not exist or points to an invalid path. Removes the broken link, logs the repair, records the removal, then delegates to createNewLink for the fresh symlink.

Parameters
$skillName : string

Description

Name of the skill with the broken symlink

$targetLink : string

Description

Absolute path to the broken symlink

$sourcePath : string

Description

Absolute path to the current packaged skill

$result : SynchronizeResult

Description

Result tracker for removed and created items

syncPackageSkills()

Private

Iterates through all packaged skills and processes each one.

private syncPackageSkills( string  $skillsDir, string  $packageSkillsPath, SynchronizeResult  $result) : void

Description

Uses Finder to locate skill directories in the package, then processes each as a potential symlink in the consumer repository.

Parameters
$skillsDir : string

Description

Target directory for symlinks

$packageSkillsPath : string

Description

Source directory containing packaged skills

$result : SynchronizeResult

Description

Result object to track outcomes