diff --git a/internal/service/auto_config.go b/internal/service/auto_config.go index dbe0e3f..a05c23a 100644 --- a/internal/service/auto_config.go +++ b/internal/service/auto_config.go @@ -372,6 +372,31 @@ func (s *AutoConfigService) BuildPipeline(req AutoConfigRequest, deploy bool) (* templateName := resolveResult.TemplateName result.Composed = resolveResult.Composed + // ---- 1.5. Clone standard template to user-editable copy ---- + if strings.HasPrefix(templateName, "std_") { + userName := strings.TrimPrefix(templateName, "std_") + if _, _, err := s.preview.readAssetJSON("templates", userName); err != nil { + raw, _, err := s.preview.readAssetJSON("templates", templateName) + if err != nil { + result.Error = fmt.Sprintf("读取标准模板失败: %v", err) + return result, fmt.Errorf(result.Error) + } + raw["name"] = userName + raw["description"] = "从 " + templateName + " 复制" + delete(raw, "source") + body, err := marshalConfigJSON(raw) + if err != nil { + result.Error = fmt.Sprintf("序列化模板失败: %v", err) + return result, fmt.Errorf(result.Error) + } + if err := s.preview.SaveTemplateAsset(userName, stringValue(raw["description"]), string(body)); err != nil { + result.Error = fmt.Sprintf("保存用户模板失败: %v", err) + return result, fmt.Errorf(result.Error) + } + } + templateName = userName + } + // ---- 2. Compose template if needed ---- if resolveResult.Composed { composed, err := s.composeFromFeatureTemplates(req.Features, resolveResult.composePrimary, resolveResult.composeFeatures) diff --git a/safesightd-linux-arm64 b/safesightd-linux-arm64 index f28e4ae..41a1d5f 100644 Binary files a/safesightd-linux-arm64 and b/safesightd-linux-arm64 differ