Files
multica/server/pkg/skillbundle/hash.go
Bohan Jiang 5038c983c0 MUL-3281: Add daemon skill bundle refs (#4445)
* feat: add daemon skill bundle refs

Co-authored-by: multica-agent <github@multica.ai>

* fix: tighten skill bundle resolve safeguards

Co-authored-by: multica-agent <github@multica.ai>

* feat: add task prepare lease

Co-authored-by: multica-agent <github@multica.ai>

* fix: isolate prepare lease concurrent index migration

Co-authored-by: multica-agent <github@multica.ai>

* fix: keep prepare lease active through start

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: J <j@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>
2026-06-23 16:19:16 +08:00

83 lines
1.6 KiB
Go

package skillbundle
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"sort"
)
const (
SourceWorkspace = "workspace"
SourceBuiltin = "builtin"
)
type File struct {
Path string
Content string
}
type Skill struct {
ID string
Source string
Name string
Description string
Content string
Files []File
}
type FileRef struct {
Path string
SHA256 string
SizeBytes int64
}
type Manifest struct {
Hash string
SizeBytes int64
FileCount int
Files []FileRef
}
func BuildManifest(skill Skill) Manifest {
files := append([]File(nil), skill.Files...)
sort.Slice(files, func(i, j int) bool {
return files[i].Path < files[j].Path
})
h := sha256.New()
writeHashPart(h, "v1")
writeHashPart(h, skill.Source)
writeHashPart(h, skill.ID)
writeHashPart(h, skill.Name)
writeHashPart(h, skill.Description)
writeHashPart(h, skill.Content)
size := int64(len(skill.Content))
refs := make([]FileRef, 0, len(files))
for _, file := range files {
fileHash := sha256.Sum256([]byte(file.Content))
fileDigest := "sha256:" + hex.EncodeToString(fileHash[:])
writeHashPart(h, file.Path)
writeHashPart(h, fileDigest)
writeHashPart(h, file.Content)
size += int64(len(file.Content))
refs = append(refs, FileRef{
Path: file.Path,
SHA256: fileDigest,
SizeBytes: int64(len(file.Content)),
})
}
return Manifest{
Hash: "sha256:" + hex.EncodeToString(h.Sum(nil)),
SizeBytes: size,
FileCount: len(files),
Files: refs,
}
}
func writeHashPart(h interface{ Write([]byte) (int, error) }, value string) {
_, _ = fmt.Fprintf(h, "%d:%s\n", len(value), value)
}