fix(droid): align hooks with Factory 0.175

This commit is contained in:
ZacharyZhang-NY committed 2026-07-20 14:34:54 -04:00
1 parent 827374e7f8
commit 4521cbe32f
15 files changed
+2749 -881

No files matched your search

+122 -45
View File
@@ -1,62 +1,139 @@
package plugins
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
func prepareRenderedDroidChange(rendered *droidRenderedDocument) (*fileChange, error) {
if rendered == nil || !rendered.changed {
return nil, nil
type droidFactoryConfigPaths struct {
directory string
root string
legacyDirectory string
legacy string
settings string
localSettings string
}
func droidFactoryPaths() (*droidFactoryConfigPaths, error) {
home, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("resolve home directory: %w", err)
}
label := "Factory Droid hooks"
if rendered.document.kind == "legacy" {
label = "Factory Droid legacy hooks"
} else if rendered.document.kind == "settings" {
label = "Factory Droid settings"
directory := filepath.Join(home, ".factory")
legacyDirectory := filepath.Join(directory, "hooks")
return &droidFactoryConfigPaths{
directory: directory,
root: filepath.Join(directory, "hooks.json"),
legacyDirectory: legacyDirectory,
legacy: filepath.Join(legacyDirectory, "hooks.json"),
settings: filepath.Join(directory, "settings.json"),
localSettings: filepath.Join(directory, "settings.local.json"),
}, nil
}
func readDroidDocument(
filePath, kind, label string,
) (*droidDocument, error) {
snapshot, err := readManagedFile(filePath, label, maxManagedSourceBytes)
if err != nil || snapshot == nil {
return nil, err
}
return prepareSourceChange(
rendered.document.filePath,
label,
rendered.document.raw,
rendered.document.exists,
rendered.next,
os.FileMode(0600),
rendered.remove,
return parseDroidDocument(
true,
filePath,
kind,
snapshot.contents,
snapshot,
)
}
func droidRuntimeFilesExist(contracts []droidRuntimeContract) (bool, error) {
for _, contract := range contracts {
configPath := filepath.Join(filepath.Dir(contract.guardPath), "config.json")
raw, exists, err := readOptionalFile(configPath, "Elydora runtime config")
func readDroidSources() (*droidSources, error) {
paths, err := droidFactoryPaths()
if err != nil {
return nil, err
}
if _, err := managedPhysicalDirectoryExists(
paths.directory,
"Factory Droid user configuration directory",
); err != nil {
return nil, err
}
if _, err := managedPhysicalDirectoryExists(
paths.legacyDirectory,
"Factory Droid legacy hooks directory",
); err != nil {
return nil, err
}
root, err := readDroidDocument(paths.root, "hooks", "Factory Droid user hooks")
if err != nil {
return nil, err
}
if root == nil {
root, err = createOwnedDroidDocument(paths.root)
if err != nil {
return false, err
}
if !exists {
continue
}
var config map[string]any
if err := json.Unmarshal(raw, &config); err != nil {
return false, fmt.Errorf("parse Elydora runtime config at %s: %w", configPath, err)
}
agentID, ok := config["agent_id"].(string)
if !ok || config["agent_name"] != droidAgentKey || !sameDroidAgentID(agentID, contract.agentID) {
continue
}
guardExists, err := regularFileExists(contract.guardPath, "Elydora guard runtime")
if err != nil {
return false, err
}
auditExists, err := regularFileExists(contract.auditPath, "Elydora audit runtime")
if err != nil {
return false, err
}
if guardExists && auditExists {
return true, nil
return nil, err
}
}
return false, nil
legacy, err := readDroidDocument(paths.legacy, "legacy", "Factory Droid legacy hooks")
if err != nil {
return nil, err
}
if legacy == nil {
legacy, err = createDroidDocument(paths.legacy, "legacy", []byte("{}\n"))
if err != nil {
return nil, err
}
}
settings, err := readDroidDocument(paths.settings, "settings", "Factory Droid user settings")
if err != nil {
return nil, err
}
if settings == nil {
settings, err = createDroidDocument(paths.settings, "settings", []byte("{}\n"))
if err != nil {
return nil, err
}
}
localSettings, err := readDroidDocument(
paths.localSettings,
"local-settings",
"Factory Droid local settings",
)
if err != nil {
return nil, err
}
if localSettings == nil {
localSettings, err = createDroidDocument(
paths.localSettings,
"local-settings",
[]byte("{}\n"),
)
if err != nil {
return nil, err
}
}
policy, err := readDroidPolicy()
if err != nil {
return nil, err
}
return &droidSources{
root: root,
legacy: legacy,
settings: settings,
localSettings: localSettings,
policy: policy,
}, nil
}
func requireDroidHooksEnabled(sources *droidSources) error {
if blocked := droidHookBlocked(sources); blocked != nil {
return fmt.Errorf(
"Factory Droid user hooks are disabled by %s in %s at %s",
blocked.field,
blocked.label,
blocked.filePath,
)
}
return nil
}