Token导航 LogoToken导航

Agent Skill · 研究检索

feature-flags(特征标志)

feature-flags 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

feature-flags 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 61,129。

总安装 356周安装 15GitHub Stars 15下载 125核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:feature-flags(特征标志)
来源仓库:https://github.com/wshaddix/dotnet-skills
仓库路径:skills/feature-flags
安装命令:
npx skills add https://github.com/wshaddix/dotnet-skills --skill feature-flags
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/wshaddix/dotnet-skills --skill feature-flags

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

feature-flags 用于查找、检索和筛选相关信息。适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词快速定位候选结果。通过 npx skills add 命令从指定 GitHub 仓库安装并使用。安装前需确认权限范围、维护状态,避免触发联网或命令执行。

适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/feature-flags

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/wshaddix/dotnet-skills --skill feature-flags;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

feature-flags 怎么安装?

在终端执行 npx skills add https://github.com/wshaddix/dotnet-skills --skill feature-flags。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

feature-flags 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

feature-flags 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

feature-flags 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

feature-flags 用的人多吗?

公开数据是累计安装 356 次,近一周安装 15 次,下载 125 次,GitHub 15 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

feature-flags 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
feature-flags

特征标志 · 本页

35615需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Rationale

Feature flags enable safe deployments, gradual rollouts, A/B testing, and quick rollback capabilities. Without proper feature flag patterns, teams risk deploying incomplete features or cannot respond quickly to production issues. These patterns provide a robust, maintainable approach to feature management in Razor Pages applications.

Patterns

Pattern 1: Configuration-Based Feature Flags

Use appsettings.json for simple feature toggles with environment-specific overrides.

// appsettings.json
{
  "FeatureManagement": {
    "NewDashboard": false,
    "BetaFeature": false,
    "DarkMode": true,
    "PaymentV2": {
      "EnabledFor": [
        {
          "Name": "Microsoft.Targeting",
          "Parameters": {
            "Audience": {
              "Users": [ "admin@example.com" ],
              "Groups": [ "BetaTesters" ],
              "DefaultRolloutPercentage": 0
            }
          }
        }
      ]
    }
  }
}

// appsettings.Production.json
{
  "FeatureManagement": {
    "NewDashboard": true,
    "PaymentV2": {
      "EnabledFor": [
        {
          "Name": "Microsoft.Targeting",
          "Parameters": {
            "Audience": {
              "Users": [ "admin@example.com" ],
              "Groups": [ "BetaTesters" ],
              "DefaultRolloutPercentage": 25
            }
          }
        }
      ]
    }
  }
}
// Program.cs - Basic setup
builder.Services.AddFeatureManagement();

// With custom configuration section
builder.Services.AddFeatureManagement(
    builder.Configuration.GetSection("FeatureManagement"));

// With feature filters
builder.Services.AddFeatureManagement()
    .AddFeatureFilter<TargetingFilter>()
    .AddFeatureFilter<PercentageFilter>()
    .AddFeatureFilter<TimeWindowFilter>();

Pattern 2: Typed Feature Flags

Create strongly-typed feature flags for compile-time safety and discoverability.

// Feature flag constants
public static class FeatureFlags
{
    public const string NewDashboard = "NewDashboard";
    public const string BetaFeature = "BetaFeature";
    public const string DarkMode = "DarkMode";
    public const string PaymentV2 = "PaymentV2";
    public const string ApiRateLimiting = "ApiRateLimiting";
    public const string AdvancedReporting = "AdvancedReporting";
}

// Feature-aware service interface
public interface IFeatureAwareService
{
    Task<bool> IsEnabledAsync(string featureName);
    Task<bool> IsEnabledAsync<TContext>(string featureName, TContext context);
}

public class FeatureService : IFeatureAwareService
{
    private readonly IFeatureManager _featureManager;

    public FeatureService(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }

    public Task<bool> IsEnabledAsync(string featureName) =>
        _featureManager.IsEnabledAsync(featureName);

    public Task<bool> IsEnabledAsync<TContext>(string featureName, TContext context) =>
        _featureManager.IsEnabledAsync(featureName, context);
}

// Extension methods for easier usage
public static class FeatureManagerExtensions
{
    public static Task<bool> IsNewDashboardEnabledAsync(this IFeatureManager manager) =>
        manager.IsEnabledAsync(FeatureFlags.NewDashboard);

    public static Task<bool> IsPaymentV2EnabledAsync(this IFeatureManager manager, string userId) =>
        manager.IsEnabledAsync(FeatureFlags.PaymentV2, new TargetingContext { UserId = userId });
}

Pattern 3: Razor Pages Integration

Use feature flags in Razor Pages for conditional UI rendering and routing.

// PageModel with feature flag checks
public class DashboardModel : PageModel
{
    private readonly IFeatureManager _featureManager;

    public DashboardModel(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }

    public bool UseNewDashboard { get; private set; }
    public bool IsDarkModeEnabled { get; private set; }

    public async Task OnGetAsync()
    {
        UseNewDashboard = await _featureManager.IsEnabledAsync(FeatureFlags.NewDashboard);
        IsDarkModeEnabled = await _featureManager.IsEnabledAsync(FeatureFlags.DarkMode);
    }
}

// View with conditional rendering
@page
@model DashboardModel
@inject IFeatureManager FeatureManager

@if (Model.UseNewDashboard)
{
    <partial name="_NewDashboard" model="Model" />
}
else
{
    <partial name="_LegacyDashboard" model="Model" />
}

@if (await FeatureManager.IsEnabledAsync(FeatureFlags.BetaFeature))
{
    <div class="alert alert-info">
        <strong>Beta:</strong> Try our new experimental features!
    </div>
}

@if (Model.IsDarkModeEnabled)
{
    <button id="theme-toggle" class="btn btn-outline-secondary">
        Toggle Dark Mode
    </button>
}

Pattern 4: Feature Gate Action Filter

Use the built-in feature gate filter for controller/page-level feature control.

// Controller/PageModel level feature gate
[FeatureGate(FeatureFlags.BetaFeature)]
public class BetaFeaturesModel : PageModel
{
    public void OnGet()
    {
        // This page is only accessible when BetaFeature is enabled
    }
}

// Alternative: Redirect to different page
[FeatureGate(FeatureFlags.NewDashboard,
    RequirementType.All,  // All features must be enabled
    NoFeatureRedirect = "/Dashboard/Legacy")]
public class NewDashboardModel : PageModel
{
    // Redirects to legacy dashboard if NewDashboard is disabled
}

// Custom feature gate attribute for complex scenarios
public class PremiumFeatureAttribute : FeatureGateAttribute
{
    public PremiumFeatureAttribute()
        : base(FeatureFlags.AdvancedReporting)
    {
    }
}

[PremiumFeature]
public class ReportsModel : PageModel
{
    // Premium feature page
}

Pattern 5: Gradual Rollout with Targeting

Implement user-based and percentage-based rollouts safely.

// Custom targeting context
public class FeatureTargetingContext : ITargetingContext
{
    public string? UserId { get; set; }
    public List<string> Groups { get; set; } = new();
}

// Targeting context accessor
public class HttpContextTargetingContextAccessor : ITargetingContextAccessor
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HttpContextTargetingContextAccessor(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public ValueTask<TargetingContext> GetContextAsync()
    {
        var httpContext = _httpContextAccessor.HttpContext;

        if (httpContext?.User?.Identity?.IsAuthenticated != true)
        {
            return ValueTask.FromResult(new TargetingContext());
        }

        var context = new TargetingContext
        {
            UserId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value,
            Groups = httpContext.User.FindAll(ClaimTypes.Role)
                .Select(c => c.Value)
                .ToList()
        };

        return ValueTask.FromResult(context);
    }
}

// Registration
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<ITargetingContextAccessor, HttpContextTargetingContextAccessor>();
builder.Services.AddFeatureManagement()
    .AddFeatureFilter<TargetingFilter>();

// Usage in PageModel
public class CheckoutModel : PageModel
{
    private readonly IFeatureManager _featureManager;

    public CheckoutModel(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }

    public async Task<IActionResult> OnPostAsync()
    {
        var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "anonymous";

        if (await _featureManager.IsEnabledAsync(FeatureFlags.PaymentV2, new
        {
            UserId = userId,
            Groups = User.FindAll(ClaimTypes.Role).Select(c => c.Value).ToList()
        }))
        {
            return await ProcessPaymentV2Async();
        }

        return await ProcessLegacyPaymentAsync();
    }
}

Pattern 6: Time-Based Feature Flags

Enable features automatically during specific time windows.

{
  "FeatureManagement": {
    "HolidayTheme": {
      "EnabledFor": [
        {
          "Name": "Microsoft.TimeWindow",
          "Parameters": {
            "Start": "2024-12-01T00:00:00Z",
            "End": "2025-01-02T00:00:00Z"
          }
        }
      ]
    },
    "MaintenanceMode": {
      "EnabledFor": [
        {
          "Name": "Microsoft.TimeWindow",
          "Parameters": {
            "Start": "2024-12-25T02:00:00Z",
            "End": "2024-12-25T04:00:00Z"
          }
        }
      ]
    }
  }
}
// Time window filter usage
[FeatureGate(FeatureFlags.MaintenanceMode)]
public class MaintenanceModel : PageModel
{
    public IActionResult OnGet()
    {
        // Show maintenance page only during window
        return Page();
    }
}

// Custom time-based filter for recurring schedules
public class RecurringTimeFilter : IFeatureFilter
{
    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        var settings = context.Parameters.Get<RecurringTimeSettings>();

        if (settings?.DaysOfWeek is null || settings.DaysOfWeek.Length == 0)
        {
            return Task.FromResult(true);
        }

        var now = DateTime.UtcNow;
        var dayOfWeek = now.DayOfWeek.ToString();

        return Task.FromResult(settings.DaysOfWeek.Contains(dayOfWeek));
    }
}

public class RecurringTimeSettings
{
    public string[] DaysOfWeek { get; set; } = Array.Empty<string>();
}

Pattern 7: Middleware and Pipeline Integration

Integrate feature flags with middleware for request-level control.

// Feature flag middleware
public class FeatureFlagMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<FeatureFlagMiddleware> _logger;

    public FeatureFlagMiddleware(RequestDelegate next, ILogger<FeatureFlagMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(
        HttpContext context,
        IFeatureManager featureManager)
    {
        // Add feature flags to HttpContext.Items for views
        var flags = new Dictionary<string, bool>
        {
            [FeatureFlags.NewDashboard] = await featureManager.IsEnabledAsync(FeatureFlags.NewDashboard),
            [FeatureFlags.DarkMode] = await featureManager.IsEnabledAsync(FeatureFlags.DarkMode)
        };

        context.Items["FeatureFlags"] = flags;

        // Check for API rate limiting feature
        if (await featureManager.IsEnabledAsync(FeatureFlags.ApiRateLimiting))
        {
            _logger.LogDebug("API rate limiting is enabled");
        }

        await _next(context);
    }
}

// Extension method
public static class FeatureFlagMiddlewareExtensions
{
    public static IApplicationBuilder UseFeatureFlags(this IApplicationBuilder app)
    {
        return app.UseMiddleware<FeatureFlagMiddleware>();
    }
}

// Usage in Program.cs
app.UseFeatureFlags();

// View helper
public static class FeatureFlagHelpers
{
    public static bool IsFeatureEnabled(this IHtmlHelper helper, string featureName)
    {
        var flags = helper.ViewContext.HttpContext.Items["FeatureFlags"]
            as Dictionary<string, bool>;

        return flags?.TryGetValue(featureName, out var enabled) == true && enabled;
    }
}

// View usage
@if (Html.IsFeatureEnabled(FeatureFlags.DarkMode))
{
    <script>/* Dark mode logic */</script>
}

Anti-Patterns

// ❌ BAD: Hard-coded feature checks scattered throughout code
if (Environment.IsDevelopment())
{
    ShowNewFeature();
}

// ✅ GOOD: Use feature manager
if (await _featureManager.IsEnabledAsync(FeatureFlags.NewFeature))
{
    ShowNewFeature();
}

// ❌ BAD: Checking features in tight loops
for (var item in items)
{
    if (await _featureManager.IsEnabledAsync(FeatureFlags.BatchProcessing))
    {
        ProcessBatch(item);
    }
}

// ✅ GOOD: Check once and cache result
var useBatchProcessing = await _featureManager.IsEnabledAsync(FeatureFlags.BatchProcessing);
foreach (var item in items)
{
    if (useBatchProcessing)
    {
        ProcessBatch(item);
    }
}

// ❌ BAD: Not handling missing configuration
public async Task<bool> IsNewFeatureEnabled()
{
    return await _featureManager.IsEnabledAsync("NewFeature"); // May throw!
}

// ✅ GOOD: Use constants and handle gracefully
public async Task<bool> IsNewFeatureEnabled()
{
    try
    {
        return await _featureManager.IsEnabledAsync(FeatureFlags.NewFeature);
    }
    catch (FeatureManagementException ex)
    {
        _logger.LogWarning(ex, "Feature flag check failed");
        return false; // Safe fallback
    }
}

// ❌ BAD: Tight coupling to feature manager in domain logic
public class OrderService
{
    private readonly IFeatureManager _featureManager; // Shouldn't be here!

    public async Task ProcessOrder(Order order)
    {
        if (await _featureManager.IsEnabledAsync("NewPricing"))
        {
            ApplyNewPricing(order);
        }
    }
}

// ✅ GOOD: Pass feature-driven behavior as configuration/strategy
public class OrderService
{
    private readonly IPricingStrategy _pricingStrategy;

    public OrderService(IPricingStrategy pricingStrategy)
    {
        _pricingStrategy = pricingStrategy;
    }

    public Task ProcessOrder(Order order)
    {
        _pricingStrategy.ApplyPricing(order);
        // ...
    }
}

// ❌ BAD: Not cleaning up old feature flags
// appsettings.json has 50+ old flags never cleaned up

// ✅ GOOD: Regular cleanup process
// 1. Document feature flag lifecycle
// 2. Remove flags after feature is fully rolled out
// 3. Use feature flag dashboard for tracking

// ❌ BAD: Inconsistent naming conventions
{
  "new_feature": true,
  "LegacyFeature": false,
  "AnotherFeature_V2": true
}

// ✅ GOOD: Consistent naming (PascalCase recommended)
{
  "NewFeature": true,
  "LegacyFeature": false,
  "AnotherFeatureV2": true
}

// ❌ BAD: Enabling features without monitoring
await _featureManager.IsEnabledAsync("ExpensiveFeature");
// No metrics on usage!

// ✅ GOOD: Instrument feature flag usage
public async Task<bool> IsEnabledWithMetrics(string featureName)
{
    var enabled = await _featureManager.IsEnabledAsync(featureName);

    _metrics.RecordFeatureFlagCheck(featureName, enabled);

    return enabled;
}

References

平台分布

Codex

36.09%
按下载量换算45

Claude

31.49%
按下载量换算39

Cursor

17.08%
按下载量换算21

Gemini CLI

10.1%
按下载量换算13

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills