Files
Elydora-Go-SDK/cmd/elydora/plugins/cline_io.go
T

148 lines
3.3 KiB
Go

package plugins
import "fmt"
func validateClineHookDirectories(paths clineHookPaths) error {
if _, err := managedPhysicalDirectoryExists(
paths.clineDirectory,
"Cline configuration directory",
); err != nil {
return err
}
_, err := managedPhysicalDirectoryExists(
paths.hooksDirectory,
"Cline hooks directory",
)
return err
}
func readClineHookFile(filePath string) (clineHookFile, error) {
snapshot, err := readManagedFile(filePath, "Cline hook", maxManagedSourceBytes)
if err != nil {
return clineHookFile{}, err
}
if snapshot == nil {
return clineHookFile{filePath: filePath}, nil
}
source := string(snapshot.contents)
metadata, err := parseClineMetadata(filePath, source)
if err != nil {
return clineHookFile{}, err
}
return clineHookFile{
exists: true, filePath: filePath, source: source, metadata: metadata,
}, nil
}
func readClineHookPair() (
clineHookPaths,
clineHookFile,
clineHookFile,
error,
) {
paths, err := resolveClineHookFiles()
if err != nil {
return clineHookPaths{}, clineHookFile{}, clineHookFile{}, err
}
if err := validateClineHookDirectories(paths); err != nil {
return paths, clineHookFile{}, clineHookFile{}, err
}
guard, err := readClineHookFile(paths.guardPath)
if err != nil {
return paths, clineHookFile{}, clineHookFile{}, err
}
audit, err := readClineHookFile(paths.auditPath)
if err != nil {
return paths, clineHookFile{}, clineHookFile{}, err
}
return paths, guard, audit, nil
}
func requireAvailableClineHook(file clineHookFile) error {
if file.exists && file.metadata == nil {
return fmt.Errorf(
"Cline hook at %s already exists and is owned by another integration",
file.filePath,
)
}
return nil
}
func writeClineHookChanges(
changes []*fileChange,
label string,
rename renameFunc,
paths clineHookPaths,
) error {
if !hasClineChanges(changes) {
return nil
}
if err := ensureManagedDirectory(
paths.clineDirectory,
"Cline configuration directory",
); err != nil {
return err
}
if err := ensureManagedDirectory(paths.hooksDirectory, "Cline hooks directory"); err != nil {
return err
}
return writeChanges(changes, label, rename)
}
func writeClineChanges(
changes []*fileChange,
label string,
rename renameFunc,
paths *clineRuntimePaths,
) error {
if !hasClineChanges(changes) {
return nil
}
if err := EnsurePrivateDirectory(paths.runtimeRoot); err != nil {
return err
}
if err := EnsurePrivateDirectory(paths.agentDirectory); err != nil {
return err
}
return writeClineHookChanges(changes, label, rename, paths.hooks)
}
func hasClineChanges(changes []*fileChange) bool {
for _, change := range changes {
if change != nil {
return true
}
}
return false
}
func prepareClineUninstallChanges(
files []clineHookFile,
agentID string,
) ([]*fileChange, error) {
changes := make([]*fileChange, 0, len(files))
for _, file := range files {
if file.metadata == nil ||
(agentID != "" && !sameClineAgentID(file.metadata.AgentID, agentID)) {
continue
}
if err := assertClineWrapperIntegrity(file); err != nil {
return nil, err
}
change, err := prepareSourceChange(
file.filePath,
fmt.Sprintf("Cline %s hook", file.metadata.Kind),
[]byte(file.source),
file.exists,
nil,
0700,
true,
)
if err != nil {
return nil, err
}
changes = append(changes, change)
}
return changes, nil
}