Agent Skillssimstudioai/sim › add-feature-flag

add-feature-flag

GitHub

为Sim系统添加运行时功能标志,支持基于AWS AppConfig的全局或精细化(组织/用户/管理员)控制,并处理非生产环境的密钥回退。

.agents/skills/add-feature-flag/SKILL.md simstudioai/sim

Trigger Scenarios

需要动态开启或关闭某项功能 需要按组织、用户或管理员角色进行灰度发布 配置新的功能开关及其回退逻辑

Install

npx skills add simstudioai/sim --skill add-feature-flag -g -y
More Options

Non-standard path

npx skills add https://github.com/simstudioai/sim/tree/main/.agents/skills/add-feature-flag -g -y

Use without installing

npx skills use simstudioai/sim@add-feature-flag

指定 Agent (Claude Code)

npx skills add simstudioai/sim --skill add-feature-flag -a claude-code -g -y

安装 repo 全部 skill

npx skills add simstudioai/sim --all -g -y

预览 repo 内 skill

npx skills add simstudioai/sim --list

SKILL.md

Frontmatter
{
    "name": "add-feature-flag",
    "description": "Add a runtime feature flag (AppConfig-backed on prod, secret fallback off-prod), global by default or optionally gated by org id, user id, or platform admin",
    "argument-hint": "<flag-name>"
}

Add Feature Flag Skill

You add a runtime feature flag to Sim that can change on prod with no redeploy (AWS AppConfig). Prefer a global on/off flag unless the rollout actually needs per-organization, per-user, or platform-admin targeting. When AppConfig isn't the source of truth, the flag falls back to a single secret (on/off only).

When to use this vs env-flags.ts

  • Feature flag (@/lib/core/config/feature-flags.ts): runtime global on/off by default, optionally scoped by userId/orgId/admin. This skill.
  • Env flag (@/lib/core/config/env-flags.ts): deploy-time capability/environment detection (isProd, isHosted, isBillingEnabled). A module-load boolean. Do not add gated flags here.

If the user wants a fixed per-deployment toggle, send them to env-flags.ts instead.

The flag model

A flag's gating rule lives only in the hosted AppConfig document. It is ON for a context when any configured clause matches:

interface FeatureFlagRule {
  enabled?: boolean   // global default for everyone
  orgIds?: string[]   // allowlisted organization ids
  userIds?: string[]  // allowlisted user ids
  adminEnabled?: boolean // platform admins (user.role === 'admin')
}

Critically, none of this is expressible in code — gating (especially adminEnabled) can only be set through AppConfig, so no environment can grant access from a code literal. Off-AppConfig (self-hosted/OSS/local), a flag is simply on or off, derived from its fallback secret.

Steps

  1. Confirm the granularity before editing code. If the user has not already specified it, stop and ask:

    Should <flag-name> be a global on/off flag (recommended), or does it need rollout targeting by organization, user, and/or platform admin?

    • Recommend global. Do not infer scoped gating merely because the call site already has a user or organization id.
    • If the user chooses scoped gating but does not name the dimensions, ask which of organization, user, and platform admin it needs. Wire only the selected dimensions.
    • If the user wants a fixed per-deployment toggle rather than a runtime AppConfig flag, use env-flags.ts instead.
  2. Define the flag. Add one entry to the FEATURE_FLAGS registry in apps/sim/lib/core/config/feature-flags.ts. Each entry is the flag's whole definition — name (kebab-case key), description, and the fallback secret consulted when AppConfig isn't the source of truth (truthy ⇒ on globally):

    const FEATURE_FLAGS = {
      '<flag-name>': {
        description: '<what this gates>',
        fallback: '<FLAG_SECRET>',
      },
    }
    

    fallback is the env/secret key (typed as keyof typeof env), so add <FLAG_SECRET> to apps/sim/lib/core/config/env.ts first (and the deployment's secret store) — it won't typecheck otherwise. Do not add org/user/admin defaults here — that gating exists only in AppConfig. Adding the entry makes <flag-name> a valid FeatureFlagName.

  3. Gate the call site at the chosen granularity. For the recommended global mode, pass no context:

    import { isFeatureEnabled } from '@/lib/core/config/feature-flags'
    
    if (await isFeatureEnabled('<flag-name>')) {
      // gated behavior
    }
    

    Do not fetch, resolve, or thread through user or organization context solely for a global flag.

    For scoped rollout, pass only the dimensions the user selected. Admin status is resolved internally, so ordinary callers pass userId, not a role:

    import { isFeatureEnabled } from '@/lib/core/config/feature-flags'
    
    if (await isFeatureEnabled('<flag-name>', { userId, orgId })) {
      // gated behavior
    }
    
    • Organization targeting uses orgId; user and platform-admin targeting require userId.
    • Missing ids are fine — a clause with no matching id is skipped; with no userId, the admin clause resolves to false without a DB read.
    • Admin routes that already know the caller is an admin may pass { userId, isAdmin: true } to skip the role lookup.
    • Client/UI flags: resolve server-side (in a server component, route, or loader) and pass the boolean down as a prop. There is no client AppConfig.
  4. (Prod) configure in AppConfig. The infra feature-flags profile schema is permissive, so a new flag needs no infra change. Operators add the flag to the hosted feature-flags document using enabled for global rollout or only the selected orgIds/userIds/adminEnabled clauses for scoped rollout, then start a sim-<env>-fast deployment (see the AppConfig runbook in the infra README — same flow as access-control). The fallback secret only applies when AppConfig is disabled.

  5. Test. Add a case to apps/sim/lib/core/config/feature-flags.test.ts that matches the chosen granularity. For a global flag, exercise isFeatureEnabled('<flag-name>') with an AppConfig enabled rule and toggle the fallback secret for the off-AppConfig path. For scoped rollout, cover only the selected clauses and mock isPlatformAdmin when testing adminEnabled.

  6. Clean up after rollout. When the feature ships to everyone, delete the flag's entry from FEATURE_FLAGS, the <FLAG_SECRET> env entry, the AppConfig document, the call sites, and the test. Leaving dead flags around is the main failure mode of flag systems.

Notes

  • Flag keys are kebab-case.
  • Never read flags via raw fetch or a new AppConfig client — always go through isFeatureEnabled / getFeatureFlags.
  • Never bake gating into code. The fallback is a single boolean secret; org/user/admin scoping is AppConfig-only.
  • Never add or propagate request context unless the user chose scoped rollout.
  • The admin check reads the DB replica (dbReplica) and is resolved lazily, so an admin-gated flag adds at most one cheap replica read, and only when adminEnabled is the deciding clause.

Version History

  • ceda457 Current 2026-08-20 15:28

Same Skill Collection

.agents/skills/add-block-preview/SKILL.md
.agents/skills/add-block/SKILL.md
.agents/skills/add-column-type/SKILL.md
.agents/skills/add-connector/SKILL.md
.agents/skills/add-enrichment/SKILL.md
.agents/skills/add-hosted-key/SKILL.md
.agents/skills/add-integration/SKILL.md
.agents/skills/add-managed-cli/SKILL.md
.agents/skills/add-model/SKILL.md
.agents/skills/add-tools/SKILL.md
.agents/skills/add-trigger/SKILL.md
.agents/skills/babysit/SKILL.md
.agents/skills/cleanup/SKILL.md
.agents/skills/council/SKILL.md
.agents/skills/db-migrate/SKILL.md
.agents/skills/design-taste-frontend/SKILL.md
.agents/skills/emcn-design-review/SKILL.md
.agents/skills/emil-design-eng/SKILL.md
.agents/skills/make-interfaces-feel-better/SKILL.md
.agents/skills/memory-load-check/SKILL.md
.agents/skills/react-query-best-practices/SKILL.md
.agents/skills/ship/SKILL.md
.agents/skills/tool-registry-boundary/SKILL.md
.agents/skills/v2-api-conventions/SKILL.md
.agents/skills/validate-connector/SKILL.md
.agents/skills/validate-integration/SKILL.md
.agents/skills/validate-model/SKILL.md
.agents/skills/validate-trigger/SKILL.md
.agents/skills/you-might-not-need-a-callback/SKILL.md
.agents/skills/you-might-not-need-a-comment/SKILL.md
.agents/skills/you-might-not-need-a-memo/SKILL.md
.agents/skills/you-might-not-need-an-effect/SKILL.md
.agents/skills/you-might-not-need-state/SKILL.md
.agents/skills/you-might-not-need-url-state/SKILL.md
.claude/skills/add-settings-page/SKILL.md
helm/sim/.claude/skills/sim-helm/SKILL.md
.agents/skills/migrate-application-operation/SKILL.md

Metadata

Files
0
Version
ceda457
Hash
d0b84603
Indexed
2026-08-20 15:28

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-25 06:24
浙ICP备14020137号-1 $방문자$