Files
HomeAgent/internal/tracker/changeset.go
root dbbd73b930 refactor: migrate built-in plugins to SDK-only interface
- Six-phase plan complete: webui/cli/healthcheck/pluginmgr/clawhubadapter
  now interact with the kernel exclusively via internal/sdk interfaces;
  all Configure() calls and package-level global injection removed
- buildSDK in internal/plugin/registry.go is the single assembly point
- Add internal/sdk/events.go exporting event types/constants
- Fix ProviderManager cooldown sharing: LuaAdaptedProvider.Name() now
  returns the source name instead of lua_<adapter>, so multiple sources
  sharing an adapter (single script load via shared VM AdapterCache) no
  longer share failure-cooldown state
- Verified: build/vet/tests green, deployed to homeagent.service with
  full plugin capability testing via local OpenAI-compatible mock
2026-08-01 12:17:17 +08:00

123 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tracker
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"path/filepath"
"time"
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
)
// DTO 已迁入内置 SDK此处保留别名以兼容现有调用方。
type ChangeType = sdk.ChangeType
const (
ChangeFileCreated = sdk.ChangeFileCreated
ChangeFileModified = sdk.ChangeFileModified
ChangeFileDeleted = sdk.ChangeFileDeleted
)
type FileChange = sdk.FileChange
type ChangeSet = sdk.ChangeSet
func NewChangeSet(action string) *ChangeSet {
return &ChangeSet{
ID: fmt.Sprintf("cs_%d", time.Now().UnixNano()),
Action: action,
Timestamp: time.Now(),
}
}
func fileHash(path string) (string, int64, error) {
data, err := os.ReadFile(path)
if err != nil {
return "", 0, err
}
h := sha256.Sum256(data)
return hex.EncodeToString(h[:]), int64(len(data)), nil
}
func fileInfo(path string) (size int64, modTime time.Time, err error) {
info, err := os.Stat(path)
if err != nil {
return 0, time.Time{}, err
}
return info.Size(), info.ModTime(), nil
}
type FSState struct {
Files map[string]FileChange `json:"files"`
Root string `json:"root"`
}
func captureFSState(root string) (*FSState, error) {
state := &FSState{
Files: make(map[string]FileChange),
Root: root,
}
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
return err
}
rel, _ := filepath.Rel(root, path)
hash, size, err := fileHash(path)
if err != nil {
return nil
}
state.Files[rel] = FileChange{
Path: rel,
HashAfter: hash,
SizeAfter: size,
}
return nil
})
return state, err
}
func diffStates(before, after *FSState) []FileChange {
var changes []FileChange
if before == nil || after == nil {
return changes
}
seen := make(map[string]bool)
for path, afterFile := range after.Files {
seen[path] = true
if beforeFile, ok := before.Files[path]; ok {
if beforeFile.HashAfter != afterFile.HashAfter {
changes = append(changes, FileChange{
Path: path,
Type: ChangeFileModified,
HashBefore: beforeFile.HashAfter,
HashAfter: afterFile.HashAfter,
SizeBefore: beforeFile.SizeAfter,
SizeAfter: afterFile.SizeAfter,
})
}
} else {
changes = append(changes, FileChange{
Path: path,
Type: ChangeFileCreated,
HashAfter: afterFile.HashAfter,
SizeAfter: afterFile.SizeAfter,
})
}
}
for path := range before.Files {
if !seen[path] {
changes = append(changes, FileChange{
Path: path,
Type: ChangeFileDeleted,
HashBefore: before.Files[path].HashAfter,
SizeBefore: before.Files[path].SizeAfter,
})
}
}
return changes
}