Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

264 lines
11 KiB
Go

package agentextension
import (
"errors"
"fmt"
"net/url"
"regexp"
"strings"
agentextensionbiz "github.com/tutti-os/tutti/services/tuttid/biz/agentextension"
)
var runtimeBinaryNamePattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`)
var runtimeSearchPathPattern = regexp.MustCompile(`^[A-Za-z0-9._-]+(?:/[A-Za-z0-9._-]+)*$`)
var runtimeConstraintPartPattern = regexp.MustCompile(`^(?:>=|>|<=|<)[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$`)
var runtimeArgumentPlaceholderPattern = regexp.MustCompile(`\$\{[^}]+\}`)
var runtimeEnvironmentKeyPattern = regexp.MustCompile(`^[A-Z][A-Z0-9_]{0,127}$`)
var runtimeEnvironmentReferencePattern = regexp.MustCompile(`^\$\{env:(TUTTI_[A-Z0-9_]{1,120})\}$`)
var runtimeArtifactPlatformPattern = regexp.MustCompile(`^[a-z0-9]+-[a-z0-9_]+$`)
var runtimeArtifactSHA256Pattern = regexp.MustCompile(`^[a-f0-9]{64}$`)
const maxRuntimeBinaryArtifactBytes = int64(1 << 30)
func validateDiscoveryProfile(profile DiscoveryProfile) error {
if profile.SchemaVersion != "tutti.agent.discovery.v1" || len(profile.Candidates) == 0 {
return errors.New("extension discovery profile requires candidates")
}
for _, candidate := range profile.Candidates {
if len(candidate.BinaryNames) == 0 || len(candidate.Version.Args) == 0 || len(candidate.LaunchArgs) == 0 {
return errors.New("extension discovery candidate is incomplete")
}
for _, name := range candidate.BinaryNames {
if !runtimeBinaryNamePattern.MatchString(name) {
return errors.New("extension discovery binary name is invalid")
}
}
if len(candidate.SearchPaths) > 16 {
return errors.New("extension discovery has too many search paths")
}
for _, searchPath := range candidate.SearchPaths {
if searchPath.Scope != "user" || len(searchPath.Path) > 256 || !runtimeSearchPathPattern.MatchString(searchPath.Path) {
return errors.New("extension discovery search path is invalid")
}
for _, component := range strings.Split(searchPath.Path, "/") {
if component == "." || component == ".." {
return errors.New("extension discovery search path is invalid")
}
}
}
for _, argument := range append(append([]string(nil), candidate.Version.Args...), candidate.LaunchArgs...) {
if strings.TrimSpace(argument) == "" || strings.ContainsAny(argument, "|;&`\n\r<>") || strings.Contains(argument, "$(") {
return errors.New("extension discovery argument contains forbidden syntax")
}
}
for _, argument := range candidate.Version.Args {
if strings.Contains(argument, "$") {
return errors.New("extension discovery version argument contains unsupported placeholder")
}
}
parts := strings.Fields(candidate.Version.Constraint)
if len(parts) == 0 {
return errors.New("extension discovery version constraint is required")
}
for _, part := range parts {
if !runtimeConstraintPartPattern.MatchString(part) {
return errors.New("extension discovery version constraint is invalid")
}
}
if candidate.Probe.Kind != "acp-initialize" || candidate.Probe.TimeoutMS < 100 || candidate.Probe.TimeoutMS > 30000 {
return errors.New("extension discovery ACP probe is invalid")
}
}
return nil
}
func validateDiscoveryLaunchPlaceholders(profile DiscoveryProfile, composer ComposerProfile) error {
setting := composer.LaunchPermissionSetting()
for _, candidate := range profile.Candidates {
if err := validatePermissionLaunchPlaceholders(candidate.LaunchArgs, setting, false); err != nil {
return fmt.Errorf("extension discovery launch: %w", err)
}
}
return nil
}
func validateManifestLaunchPlaceholders(manifest Manifest, composer ComposerProfile) error {
if err := validatePermissionLaunchPlaceholders(manifest.Runtime.Launch.Args, composer.LaunchPermissionSetting(), true); err != nil {
return fmt.Errorf("extension runtime launch: %w", err)
}
return nil
}
func validatePermissionLaunchPlaceholders(
arguments []string,
setting *ComposerLaunchPermissionSetting,
allowRuntimePlaceholders bool,
) error {
permissionPlaceholders := 0
for _, argument := range arguments {
for _, match := range runtimeArgumentPlaceholderPattern.FindAllString(argument, -1) {
if allowRuntimePlaceholders && (match == "${projectRoot}" || match == "${installRoot}" || match == "${platform}") {
continue
}
if setting == nil || match != setting.Placeholder || argument != match {
return errors.New("argument contains unsupported placeholder")
}
permissionPlaceholders++
}
withoutKnown := runtimeArgumentPlaceholderPattern.ReplaceAllString(argument, "")
if strings.Contains(withoutKnown, "$") {
return errors.New("argument contains unsupported placeholder")
}
}
if setting != nil && permissionPlaceholders != 1 {
return errors.New("permission placeholder must appear exactly once")
}
return nil
}
func validateRuntimeContract(manifest Manifest) error {
runner := manifest.Runtime.Install.Runner
if runner != "npm" && runner != "pnpm" && runner != "uv" && runner != "binary" {
return errors.New("extension runtime install runner is unsupported")
}
if err := validateRuntimeLaunchEnvironment(manifest.Runtime.Launch.Env); err != nil {
return err
}
for _, argument := range append(append([]string(nil), manifest.Runtime.Install.Args...), manifest.Runtime.Launch.Executable) {
if strings.TrimSpace(argument) == "" || strings.ContainsAny(argument, "|;&`\n\r<>") || strings.Contains(argument, "$(") {
return errors.New("extension runtime argument contains forbidden shell syntax")
}
for _, match := range runtimeArgumentPlaceholderPattern.FindAllString(argument, -1) {
if match != "${projectRoot}" && match != "${installRoot}" && match != "${platform}" {
return errors.New("extension runtime argument contains unsupported placeholder")
}
}
withoutPlaceholders := runtimeArgumentPlaceholderPattern.ReplaceAllString(argument, "")
if strings.Contains(withoutPlaceholders, "$") {
return errors.New("extension runtime argument contains unsupported placeholder")
}
}
for _, argument := range manifest.Runtime.Launch.Args {
if strings.TrimSpace(argument) == "" || strings.ContainsAny(argument, "|;&`\n\r<>") || strings.Contains(argument, "$(") {
return errors.New("extension runtime argument contains forbidden shell syntax")
}
for _, match := range runtimeArgumentPlaceholderPattern.FindAllString(argument, -1) {
if match != "${projectRoot}" && match != "${installRoot}" && match != "${platform}" &&
(match != composerPermissionLaunchPlaceholder || argument != match) {
return errors.New("extension runtime argument contains unsupported placeholder")
}
}
withoutPlaceholders := runtimeArgumentPlaceholderPattern.ReplaceAllString(argument, "")
if strings.Contains(withoutPlaceholders, "$") {
return errors.New("extension runtime argument contains unsupported placeholder")
}
}
for _, argument := range manifest.Runtime.Install.Args {
if strings.Contains(argument, "${projectRoot}") {
return errors.New("extension runtime install cannot depend on a project root")
}
}
if !strings.HasPrefix(manifest.Runtime.Launch.Executable, "${installRoot}/") {
return errors.New("extension runtime launch must stay under installRoot")
}
if runner != "binary" && runner != "uv" && !strings.Contains(strings.Join(manifest.Runtime.Install.Args, "\x00"), "${installRoot}") {
return errors.New("extension runtime install and launch must stay under installRoot")
}
if runner == "binary" {
if len(manifest.Runtime.Install.Args) != 0 {
return errors.New("extension binary runtime cannot declare installer arguments")
}
return validateRuntimeBinaryArtifacts(manifest.Runtime.Install.Artifacts)
}
if len(manifest.Runtime.Install.Artifacts) != 0 {
return errors.New("extension package-manager runtime cannot declare binary artifacts")
}
if runner == "npm" || runner == "pnpm" {
packagePattern := regexp.MustCompile(`^@[a-z0-9._-]+/[a-z0-9._-]+@[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$`)
count := 0
for _, argument := range manifest.Runtime.Install.Args {
if strings.HasPrefix(argument, "@") {
if !packagePattern.MatchString(argument) {
return errors.New("extension runtime package must use an exact scoped version")
}
count++
}
}
if count != 1 {
return errors.New("extension runtime install must name exactly one scoped package")
}
}
if runner == "uv" {
packagePattern := regexp.MustCompile(`^[a-z0-9][a-z0-9._-]*(?:\[[a-z0-9._-]+(?:,[a-z0-9._-]+)*\])?==[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$`)
count := 0
for _, argument := range manifest.Runtime.Install.Args {
if packagePattern.MatchString(argument) {
count++
}
}
if count != 1 {
return errors.New("extension runtime install must name exactly one package at an exact version")
}
if len(manifest.Runtime.Install.Args) != 3 || manifest.Runtime.Install.Args[0] != "tool" || manifest.Runtime.Install.Args[1] != "install" || !packagePattern.MatchString(manifest.Runtime.Install.Args[2]) {
return errors.New("extension uv runtime install must use the constrained tool install form")
}
}
return nil
}
func validateRuntimeLaunchEnvironment(environment map[string]string) error {
if len(environment) > 32 {
return errors.New("extension runtime launch environment has too many entries")
}
for key, value := range environment {
if !runtimeEnvironmentKeyPattern.MatchString(key) {
return errors.New("extension runtime launch environment key is invalid")
}
if !runtimeEnvironmentReferencePattern.MatchString(strings.TrimSpace(value)) {
return errors.New("extension runtime launch environment must reference a TUTTI_* variable")
}
}
return nil
}
func validateRuntimeBinaryArtifacts(artifacts []agentextensionbiz.RuntimeBinaryArtifact) error {
if len(artifacts) == 0 || len(artifacts) > 16 {
return errors.New("extension binary runtime requires a bounded artifact catalog")
}
platforms := make(map[string]struct{}, len(artifacts))
for _, artifact := range artifacts {
if artifact.Kind != "executable" || !runtimeArtifactPlatformPattern.MatchString(artifact.Platform) {
return errors.New("extension binary artifact identity is invalid")
}
if _, exists := platforms[artifact.Platform]; exists {
return errors.New("extension binary artifact platform is duplicated")
}
platforms[artifact.Platform] = struct{}{}
if !validSemver(artifact.Version) || !runtimeArtifactSHA256Pattern.MatchString(artifact.SHA256) {
return errors.New("extension binary artifact version or SHA-256 is invalid")
}
if artifact.SizeBytes <= 0 || artifact.SizeBytes > maxRuntimeBinaryArtifactBytes {
return errors.New("extension binary artifact size is invalid")
}
if err := validateRuntimeArtifactHTTPSURL(artifact.URL); err != nil {
return fmt.Errorf("extension binary artifact URL: %w", err)
}
if artifact.Provenance.Kind != "official-release" {
return errors.New("extension binary artifact provenance is invalid")
}
if err := validateRuntimeArtifactHTTPSURL(artifact.Provenance.URL); err != nil {
return fmt.Errorf("extension binary artifact provenance URL: %w", err)
}
}
return nil
}
func validateRuntimeArtifactHTTPSURL(rawURL string) error {
parsed, err := url.Parse(rawURL)
if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil || parsed.Fragment != "" {
return errors.New("must be an HTTPS URL without credentials or fragment")
}
return nil
}