Files
CHORUS/pkg/ucxl/parser.go
anthonyrawlins 543ab216f9 Complete BZZZ functionality port to CHORUS
🎭 CHORUS now contains full BZZZ functionality adapted for containers

Core systems ported:
- P2P networking (libp2p with DHT and PubSub)
- Task coordination (COOEE protocol)
- HMMM collaborative reasoning
- SHHH encryption and security
- SLURP admin election system
- UCXL content addressing
- UCXI server integration
- Hypercore logging system
- Health monitoring and graceful shutdown
- License validation with KACHING

Container adaptations:
- Environment variable configuration (no YAML files)
- Container-optimized logging to stdout/stderr
- Auto-generated agent IDs for container deployments
- Docker-first architecture

All proven BZZZ P2P protocols, AI integration, and collaboration
features are now available in containerized form.

Next: Build and test container deployment.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 20:02:37 +10:00

247 lines
6.2 KiB
Go

package ucxl
import (
"fmt"
"net/url"
"regexp"
"strings"
)
// UCXLAddress represents a parsed UCXL address
type UCXLAddress struct {
Raw string `json:"raw"`
Agent string `json:"agent"` // Agent ID or "*" for any
Role string `json:"role"` // Agent role or "*" for any
Project string `json:"project"` // Project identifier or "*" for any
Task string `json:"task"` // Task identifier or "*" for any
Path string `json:"path"` // Resource path (optional)
Temporal string `json:"temporal"` // Temporal navigation (optional)
}
// UCXLAddressRegex matches valid UCXL address format
// Format: ucxl://agent:role@project:task/path*temporal/
var UCXLAddressRegex = regexp.MustCompile(`^ucxl://([^:]+):([^@]+)@([^:]+):([^/]+)(/[^*]*)?(\*[^/]*)?/?$`)
// ParseUCXLAddress parses a UCXL address string into its components
func ParseUCXLAddress(address string) (*UCXLAddress, error) {
if address == "" {
return nil, fmt.Errorf("empty UCXL address")
}
// Check if it starts with ucxl://
if !strings.HasPrefix(address, "ucxl://") {
return nil, fmt.Errorf("invalid UCXL address: must start with 'ucxl://'")
}
// Parse using regex
matches := UCXLAddressRegex.FindStringSubmatch(address)
if matches == nil {
return nil, fmt.Errorf("invalid UCXL address format: %s", address)
}
ucxlAddr := &UCXLAddress{
Raw: address,
Agent: matches[1],
Role: matches[2],
Project: matches[3],
Task: matches[4],
Path: strings.TrimPrefix(matches[5], "/"),
Temporal: strings.TrimPrefix(matches[6], "*"),
}
// Validate components
if err := validateUCXLComponents(ucxlAddr); err != nil {
return nil, fmt.Errorf("invalid UCXL address: %w", err)
}
return ucxlAddr, nil
}
// validateUCXLComponents validates individual components of a UCXL address
func validateUCXLComponents(addr *UCXLAddress) error {
// Agent can be any non-empty string or "*"
if addr.Agent == "" {
return fmt.Errorf("agent cannot be empty")
}
// Role can be any non-empty string or "*"
if addr.Role == "" {
return fmt.Errorf("role cannot be empty")
}
// Project can be any non-empty string or "*"
if addr.Project == "" {
return fmt.Errorf("project cannot be empty")
}
// Task can be any non-empty string or "*"
if addr.Task == "" {
return fmt.Errorf("task cannot be empty")
}
// Path is optional, but if present should be valid
if addr.Path != "" {
// URL decode and validate path
decoded, err := url.PathUnescape(addr.Path)
if err != nil {
return fmt.Errorf("invalid path encoding: %w", err)
}
addr.Path = decoded
}
// Temporal is optional
if addr.Temporal != "" {
// Validate temporal navigation syntax
if !isValidTemporal(addr.Temporal) {
return fmt.Errorf("invalid temporal navigation syntax: %s", addr.Temporal)
}
}
return nil
}
// isValidTemporal validates temporal navigation syntax
func isValidTemporal(temporal string) bool {
// Valid temporal patterns:
// ^/ - latest version
// ~/ - earliest version
// @timestamp - specific timestamp
// ~n/ - n versions back
// ^n/ - n versions forward
validPatterns := []string{
`^\^/?$`, // ^/ or ^
`^~/?$`, // ~/ or ~
`^@\d+/?$`, // @timestamp
`^~\d+/?$`, // ~n versions back
`^\^\d+/?$`, // ^n versions forward
}
for _, pattern := range validPatterns {
matched, _ := regexp.MatchString(pattern, temporal)
if matched {
return true
}
}
return false
}
// GenerateUCXLAddress creates a UCXL address from components
func GenerateUCXLAddress(agent, role, project, task, path, temporal string) (string, error) {
// Validate required components
if agent == "" || role == "" || project == "" || task == "" {
return "", fmt.Errorf("agent, role, project, and task are required")
}
// Build address
address := fmt.Sprintf("ucxl://%s:%s@%s:%s", agent, role, project, task)
// Add path if provided
if path != "" {
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
// URL encode the path
encodedPath := url.PathEscape(path)
address += encodedPath
}
// Add temporal navigation if provided
if temporal != "" {
if !strings.HasPrefix(temporal, "*") {
temporal = "*" + temporal
}
address += temporal
}
// Always end with /
if !strings.HasSuffix(address, "/") {
address += "/"
}
// Validate the generated address
_, err := ParseUCXLAddress(address)
if err != nil {
return "", fmt.Errorf("generated invalid UCXL address: %w", err)
}
return address, nil
}
// IsValidUCXLAddress checks if a string is a valid UCXL address
func IsValidUCXLAddress(address string) bool {
_, err := ParseUCXLAddress(address)
return err == nil
}
// NormalizeUCXLAddress normalizes a UCXL address to standard format
func NormalizeUCXLAddress(address string) (string, error) {
parsed, err := ParseUCXLAddress(address)
if err != nil {
return "", err
}
// Regenerate in standard format
return GenerateUCXLAddress(
parsed.Agent,
parsed.Role,
parsed.Project,
parsed.Task,
parsed.Path,
parsed.Temporal,
)
}
// MatchesPattern checks if an address matches a pattern (supports wildcards)
func (addr *UCXLAddress) MatchesPattern(pattern *UCXLAddress) bool {
// Check agent
if pattern.Agent != "*" && pattern.Agent != addr.Agent {
return false
}
// Check role
if pattern.Role != "*" && pattern.Role != addr.Role {
return false
}
// Check project
if pattern.Project != "*" && pattern.Project != addr.Project {
return false
}
// Check task
if pattern.Task != "*" && pattern.Task != addr.Task {
return false
}
// Path matching (prefix-based if pattern ends with *)
if pattern.Path != "" {
if strings.HasSuffix(pattern.Path, "*") {
prefix := strings.TrimSuffix(pattern.Path, "*")
if !strings.HasPrefix(addr.Path, prefix) {
return false
}
} else if pattern.Path != addr.Path {
return false
}
}
return true
}
// ToMap converts the UCXL address to a map for JSON serialization
func (addr *UCXLAddress) ToMap() map[string]string {
return map[string]string{
"raw": addr.Raw,
"agent": addr.Agent,
"role": addr.Role,
"project": addr.Project,
"task": addr.Task,
"path": addr.Path,
"temporal": addr.Temporal,
}
}
// String returns the string representation of the UCXL address
func (addr *UCXLAddress) String() string {
return addr.Raw
}