Agent Skills › simstudioai/sim › add-feature-flag

add-feature-flag

GitHub

用于在应用中添加运行时功能标志,支持基于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 workspace id, 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-workspace, 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 workspaceId/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
  workspaceIds?: string[] // allowlisted workspace ids
  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 workspace, organization, user, and/or platform admin?

    • Recommend global. Do not infer scoped gating merely because the call site already has a workspace, user, or organization id.
    • If the user chooses scoped gating but does not name the dimensions, ask which of workspace, 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 workspace/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>', { workspaceId, userId, orgId })) {
      // gated behavior
    }
    
    • Workspace targeting uses workspaceId; 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 workspaceIds/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 only new evaluation logic. A flag that reuses the existing clauses is already covered by apps/sim/lib/core/config/feature-flags.test.ts; add no per-flag case. When you change how flags evaluate (a new clause kind, a new fallback path), add a case there that passes the test-audit authoring gate.

  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, and the call sites. 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; workspace/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

  • 8725250 Current 2026-09-28 17:00
  • 336ec07 2026-08-29 03:05

    新增workspaceIds允许列表子句以支持按工作区限制功能标志。

  • ceda457 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-permission-group-item/SKILL.md
.agents/skills/add-selector/SKILL.md
.agents/skills/add-settings-page/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/test-audit/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-permission-group-item/SKILL.md
.agents/skills/validate-selector/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
8725250
Hash
638d8717
Indexed
2026-08-20 15:28

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-30 08:34
浙ICP备14020137号-1