diff --git a/README.md b/README.md index 660e91b..8db84ee 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Agent Skills are modular, text-based playbooks that teach an agent how to perfor | `feature-flags/launchdarkly-flag-targeting` | Control targeting, rollouts, rules, and cross-environment config | | `feature-flags/launchdarkly-flag-cleanup` | Safely remove flags from code using LaunchDarkly as the source of truth | +### Onboarding + +| Skill | Description | +|-------|-------------| +| `onboarding/launchdarkly-sdk-onboarding` | Detect tech stack, install the right SDK, validate the connection, and create a first feature flag | + ### AI Configs | Skill | Description | @@ -70,6 +76,10 @@ Roll out dark-mode to 25% of users in production Remove the `new-checkout-flow` feature flag from this codebase ``` +``` +Onboard me to LaunchDarkly — set up the SDK in this project +``` + ## Install via skills.sh CLI ```bash diff --git a/skills.json b/skills.json index 941bbad..3f53aa8 100644 --- a/skills.json +++ b/skills.json @@ -123,6 +123,23 @@ "devops", "mcp" ] + }, + { + "name": "launchdarkly-sdk-onboarding", + "description": "Onboard a project to LaunchDarkly by detecting the tech stack, installing the right SDK, initializing it, validating the connection, and creating a first feature flag. Use when the user wants to add LaunchDarkly to their project, integrate an SDK, or says 'onboard me'.", + "path": "skills/onboarding/launchdarkly-sdk-onboarding", + "version": "0.1.0", + "license": "Apache-2.0", + "compatibility": "Requires LaunchDarkly API access token. Optionally uses the LaunchDarkly MCP server for flag creation and validation.", + "tags": [ + "launchdarkly", + "onboarding", + "sdk-integration", + "feature-flags", + "getting-started", + "setup", + "mcp" + ] } ] } diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/README.md b/skills/onboarding/launchdarkly-sdk-onboarding/README.md new file mode 100644 index 0000000..a73bf54 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/README.md @@ -0,0 +1,37 @@ +# LaunchDarkly SDK Onboarding + +Onboard a project to LaunchDarkly by detecting the tech stack, installing the correct SDK, initializing it, validating the connection, and creating a first feature flag. + +## When to Use + +Use this skill when a user wants to: +- Add LaunchDarkly to their project +- Integrate a LaunchDarkly SDK +- Says "onboard me" or "set up LaunchDarkly" +- Get started with feature flags in an existing codebase + +## Workflow + +1. **Detect** — Identify language, framework, package manager, and existing SDK usage +2. **Plan** — Choose the correct SDK and generate a minimal integration plan +3. **Apply** — Install the SDK dependency and add initialization code +4. **Run** — Start the application and confirm SDK initialization +5. **Validate** — Verify LaunchDarkly sees the SDK connection +6. **First Flag** — Create a feature flag, evaluate it, and toggle it +7. **Recover** — If any step fails, diagnose and resume + +## Supported SDKs + +### Server-Side +Node.js, Python, Go, Java, Ruby, .NET, PHP, Rust, Erlang/Elixir + +### Client-Side +React, Vue, JavaScript (browser), Node.js (Electron) + +### Mobile +Swift/iOS, Android, Flutter, React Native + +## Requirements + +- LaunchDarkly account with an API access token +- LaunchDarkly MCP server (optional, enhances flag creation and validation) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md new file mode 100644 index 0000000..9e2f5a8 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md @@ -0,0 +1,174 @@ +--- +name: launchdarkly-sdk-onboarding +description: "Onboard a project to LaunchDarkly by detecting the tech stack, installing the right SDK, initializing it, validating the connection, and creating a first feature flag. Use when the user wants to add LaunchDarkly to their project, integrate an SDK, or says 'onboard me'." +license: Apache-2.0 +compatibility: Requires LaunchDarkly API access token. Optionally uses the LaunchDarkly MCP server for flag creation and validation. +metadata: + author: launchdarkly + version: "0.1.0" +--- + +# LaunchDarkly SDK Onboarding + +You're using a skill that will guide you through adding LaunchDarkly to a project. Your job is to detect the tech stack, choose the right SDK, install and initialize it, validate the connection, and help the user create their first feature flag. + +## Account and Credentials + +Before starting the SDK integration, ensure the user has access to LaunchDarkly: + +1. **Check for existing credentials**: Ask the user if they have a LaunchDarkly access token or SDK key. +2. **If the user has an account**: Use the LaunchDarkly API (`GET /api/v2/projects/PROJECT_KEY`) or `ldcli` to retrieve the project, environment, and SDK key automatically. Ask the user for permission before reading the SDK key. +3. **If the user does NOT have an account**: Prompt them to sign up at https://launchdarkly.com or log in via `ldcli login`. Guide them through creating their first project and environment if needed. +4. **SDK key types**: The project response will contain the keys you need. Use the correct key type for the SDK: + - **SDK Key** for server-side SDKs + - **Client-side ID** for client-side/browser SDKs + - **Mobile Key** for mobile SDKs + +## Core Principles + +1. **Detect, don't guess**: Always inspect the repo to determine the language, framework, and package manager. Never assume. +2. **Minimal changes**: Add SDK code alongside existing code. Don't restructure or refactor the user's project. +3. **Match existing patterns**: If the project already has conventions (env vars, config files, initialization patterns), follow them. +4. **Validate end-to-end**: Don't stop at installation. Confirm the SDK is actually connected to LaunchDarkly. + +## Workflow + +Follow these steps in order. If any step fails, go to [Step 10: Recover](#step-10-recover). + +### Step 1: Detect Repository Stack + +Before doing anything, understand the project. + +1. Inspect the repo for language, framework, and package manager +2. Check for existing LaunchDarkly SDK usage +3. Identify the application entrypoint + +See [Detect Repository Stack](references/1.0-detect.md) for detailed instructions. + +### Step 2: Generate Integration Plan + +Based on what you found, choose the correct SDK and plan the integration. + +1. Match the detected stack to an SDK using the [SDK Recipes](references/sdk-recipes.md) +2. Identify which files need to change +3. Determine if this is a server-side, client-side, or mobile integration + +See [Generate Integration Plan](references/1.1-plan.md) for detailed instructions. + +### Step 3: Install Dependencies and Apply Code + +Install the SDK and add initialization code to the project. + +1. Install the SDK package using the project's package manager +2. Add SDK initialization code to the application entrypoint +3. Configure the SDK key via environment variables + +See [Apply Code Changes](references/1.2-apply.md) for detailed instructions. + +### Step 4: Start the Application + +Verify the application runs with the SDK integrated. + +1. Start the application using its standard run command +2. Confirm there are no import or initialization errors +3. Look for SDK initialization success in logs + +See [Start the Application](references/1.3-run.md) for detailed instructions. + +### Step 5: Validate SDK Connection + +Confirm that LaunchDarkly sees the SDK connection. + +1. Check the SDK is active using the LaunchDarkly API or MCP +2. Verify the connection in the LaunchDarkly dashboard + +See [Validate SDK Connection](references/1.4-validate.md) for detailed instructions. + +### Step 6: Create Your First Feature Flag + +Help the user create and evaluate a feature flag. + +1. Create a boolean feature flag +2. Add flag evaluation code to the project +3. Toggle the flag and observe the change + +See [Create First Feature Flag](references/1.5-first-flag.md) for detailed instructions. + +### Step 7: Offer MCP Server Installation + +After the SDK is working and the first flag is toggled, check if the LaunchDarkly MCP server is installed in the user's environment. + +1. Check if `@launchdarkly/mcp-server` is configured in the user's MCP settings +2. If not installed, ask the user if they want to set it up +3. If yes, guide them through installation and configuration + +The MCP server enables richer agent-driven workflows like flag management, targeting rules, and experimentation — all without leaving the editor. + +See [MCP Server Setup](references/1.7-mcp-setup.md) for detailed instructions. + +### Step 8: Leave Behind a Setup Summary + +Generate a `LAUNCHDARKLY.md` document in the user's repository with: + +1. How LaunchDarkly was set up (SDK, package, init file, key configuration) +2. Links to the project's flags dashboard, environments, and SDK docs +3. Suggested next steps: percentage rollouts, targeting rules, experimentation, AI configs, guarded rollouts, observability +4. Useful `ldcli` commands for flag management + +This gives the user and their team a permanent reference. Ask the user for permission before committing it. + +See [Onboarding Summary](references/1.8-summary.md) for the template and detailed instructions. + +### Step 9: Install Editor Rules for Flag Management + +Leave behind editor-specific rules so the user's AI agent knows how to work with LaunchDarkly going forward. + +1. Detect which editor the user is using (Cursor, Claude Code, GitHub Copilot, etc.) +2. Create the appropriate rules file with LaunchDarkly best practices and flag management skills +3. Ask the user for permission before committing + +The rules cover: when to use flags, how to evaluate them, SDK key safety, flag hygiene, and links to documentation. + +See [Editor Rules and Skills](references/1.9-editor-rules.md) for editor-specific templates. + +### Step 10: Recover + +If any step fails, diagnose the issue and resume. + +1. Identify the failed step and error +2. Choose a recovery action +3. Resume the workflow + +See [Recovery Procedures](references/1.6-recover.md) for detailed instructions. + +## Edge Cases + +| Situation | Action | +|-----------|--------| +| SDK already installed | Skip to Step 4 (Run) or Step 5 (Validate) | +| Multiple languages in repo | Ask the user which target to integrate first (frontend vs backend vs mobile) | +| Monorepo | Identify the specific package/service to integrate and work within that subtree | +| No package manager detected | Ask the user which SDK they want to install and provide manual install instructions | +| Application won't start | Use the recover step to diagnose; don't block on run if the user confirms the app runs separately | + +## What NOT to Do + +- Don't install an SDK without detecting the stack first +- Don't hardcode SDK keys in source code — always use environment variables +- Don't restructure the user's project or refactor existing code +- Don't skip validation — always confirm the SDK is connected +- Don't create flags before the SDK connection is validated + +## References + +- [Detect Repository Stack](references/1.0-detect.md) — How to identify language, framework, and existing SDK usage +- [Generate Integration Plan](references/1.1-plan.md) — How to choose the right SDK and plan changes +- [Apply Code Changes](references/1.2-apply.md) — How to install dependencies and add initialization code +- [Start the Application](references/1.3-run.md) — How to run the app and confirm SDK initialization +- [Validate SDK Connection](references/1.4-validate.md) — How to verify LaunchDarkly sees the SDK +- [Create First Feature Flag](references/1.5-first-flag.md) — How to create, evaluate, and toggle a flag +- [Recovery Procedures](references/1.6-recover.md) — How to diagnose failures and resume +- [MCP Server Setup](references/1.7-mcp-setup.md) — How to install the LaunchDarkly MCP server +- [Onboarding Summary](references/1.8-summary.md) — Template for the setup reference document +- [Editor Rules and Skills](references/1.9-editor-rules.md) — Editor-specific rules for ongoing flag management +- [SDK Recipes](references/sdk-recipes.md) — Detection patterns, install commands, and init snippets for all SDKs diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json b/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json new file mode 100644 index 0000000..454e5ca --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json @@ -0,0 +1,21 @@ +{ + "name": "launchdarkly-sdk-onboarding", + "description": "Onboard a project to LaunchDarkly by detecting the tech stack, installing the right SDK, and validating the connection", + "version": "0.1.0", + "author": "LaunchDarkly", + "repository": "https://github.com/launchdarkly/agent-skills", + "skills": ["./"], + "tags": [ + "launchdarkly", + "onboarding", + "sdk-integration", + "feature-flags", + "getting-started", + "setup", + "mcp" + ], + "requirements": {}, + "optional": { + "mcp-servers": ["@launchdarkly/mcp-server"] + } +} diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md new file mode 100644 index 0000000..644f843 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md @@ -0,0 +1,118 @@ +--- +title: Detect Repository Stack +description: Inspect the repository to identify languages, frameworks, package managers, entrypoints, and existing SDK usage +--- + +# Detect Repository Stack + +Before installing anything, you must understand the project. This step identifies what the project is built with and whether LaunchDarkly is already present. + +## What to Detect + +### 1. Language and Framework + +Look for these files to identify the stack: + +| File | Language/Framework | +|------|--------------------| +| `package.json` | JavaScript/TypeScript (check for React, Next.js, Vue, Angular, Express, React Native, Electron, etc.) | +| `requirements.txt`, `pyproject.toml`, `Pipfile`, `setup.py` | Python (check for Django, Flask, FastAPI) | +| `go.mod` | Go (check for Gin, Echo, Fiber, Chi) | +| `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/Kotlin (check for Spring, Quarkus, Android) | +| `Gemfile` | Ruby (check for Rails, Sinatra) | +| `*.csproj`, `*.sln`, `*.fsproj` | .NET/C# (check for ASP.NET, MAUI, Xamarin, WPF, UWP) | +| `composer.json` | PHP (check for Laravel, Symfony) | +| `Cargo.toml` | Rust (check for Actix, Axum, Rocket) | +| `pubspec.yaml` | Flutter/Dart | +| `Package.swift`, `Podfile`, `*.xcodeproj` | Swift/iOS | +| `AndroidManifest.xml` | Android (also check `build.gradle` for `com.android`) | +| `rebar.config`, `mix.exs` | Erlang/Elixir | +| `CMakeLists.txt`, `Makefile` (with C/C++ patterns) | C/C++ (check for `#include` patterns) | +| `*.cabal`, `stack.yaml` | Haskell | +| `*.lua`, `rockspec` | Lua | +| `manifest`, `*.brs` | Roku (BrightScript) | +| `wrangler.toml` | Cloudflare Workers (edge SDK) | +| `vercel.json` with edge functions | Vercel Edge (edge SDK) | + +Read the dependency file to identify the specific framework. For `package.json`, check both `dependencies` and `devDependencies`. + +**If you cannot identify the language or framework**, ask the user which SDK they want to use. Present the list of available SDKs from the [SDK Recipes](sdk-recipes.md) and let them choose. + +### 2. Package Manager + +Identify how the project installs dependencies: + +| Indicator | Package Manager | +|-----------|----------------| +| `package-lock.json` | npm | +| `yarn.lock` | yarn | +| `pnpm-lock.yaml` | pnpm | +| `bun.lockb` | bun | +| `Pipfile.lock` | pipenv | +| `poetry.lock` | poetry | +| `go.sum` | go modules | +| `Gemfile.lock` | bundler | + +Use the detected package manager for all install commands. If multiple lock files exist, prefer the one that was most recently modified. + +### 3. Application Entrypoint + +Find the main file where the application starts. Common patterns: + +- **Node.js (server)**: Check `package.json` `"main"` field, or look for `index.js`, `server.js`, `app.js`, `src/index.ts` +- **Python**: Look for `app.py`, `main.py`, `manage.py`, `wsgi.py`, or the `[tool.poetry.scripts]` section +- **Go**: Look for `main.go` or `cmd/*/main.go` +- **Java**: Search for `public static void main` or `@SpringBootApplication` +- **Ruby**: Look for `config.ru`, `config/application.rb` +- **React/Vue/Angular**: Look for `src/index.tsx`, `src/main.tsx`, `src/App.tsx`, `src/main.ts` +- **React Native**: Look for `App.tsx`, `App.js`, `index.js` (with `AppRegistry.registerComponent`) +- **JavaScript (browser)**: Look for `index.html`, `src/index.js`, or bundler entry in `webpack.config.js` / `vite.config.ts` +- **Flutter**: Look for `lib/main.dart` +- **Swift/iOS**: Look for `AppDelegate.swift`, `SceneDelegate.swift`, or `@main` struct +- **Android**: Look for `MainActivity.java` or `MainActivity.kt` + +### 4. Existing LaunchDarkly SDK + +Search the codebase for existing LaunchDarkly usage: + +``` +Search for: launchdarkly, ldclient, ld-client, LDClient, @launchdarkly, launchdarkly- +``` + +Check: +- Is the SDK already in the dependency file? +- Is there initialization code? +- Is it properly configured or partially set up? +- Are there already feature flag evaluations? + +## SDK Confirmation + +After detecting the stack, confirm the SDK choice with the user: + +- **If one SDK is clearly the right fit**: Tell the user which SDK you recommend and ask for confirmation before proceeding. +- **If multiple SDKs could apply** (e.g., a Next.js project with both server and client components): Ask the user whether they want to integrate one or multiple SDKs, and which to start with. +- **If you cannot determine the right SDK**: Present the available options from the [SDK Recipes](sdk-recipes.md) and ask the user to choose. + +## Decision Tree + +After detection and confirmation: + +- **SDK already installed and initialized** -> Skip to [Validate SDK Connection](1.4-validate.md) +- **SDK installed but not initialized** -> Skip to [Apply Code Changes](1.2-apply.md) (just add init code) +- **SDK not present** -> Continue to [Generate Integration Plan](1.1-plan.md) +- **Multiple targets detected (e.g., frontend + backend)** -> Ask the user which to integrate first +- **Language not detected** -> Ask the user which SDK they want to use + +## Status + +Before beginning, report: + +``` +[STATUS] Inspecting repository structure +[STATUS] Detecting language and framework +[STATUS] Checking for existing LaunchDarkly SDK +``` + +--- + +**Upon completion, continue with:** [Generate Integration Plan](1.1-plan.md) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md new file mode 100644 index 0000000..66ddb32 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md @@ -0,0 +1,100 @@ +--- +title: Generate Integration Plan +description: Choose the correct SDK based on detected stack and generate a minimal integration plan +--- + +# Generate Integration Plan + +Based on what you detected in the previous step, choose the right SDK and plan the minimal set of changes needed. + +## Choose the Right SDK + +Use the [SDK Recipes](sdk-recipes.md) reference to match the detected stack to an SDK. The key decision: + +| Project Type | SDK Type | Key Type | +|-------------|----------|----------| +| Backend API, server-rendered app, CLI tool | Server-side SDK | SDK Key | +| Browser SPA (React, Vue, Angular, vanilla JS) | Client-side SDK | Client-side ID | +| iOS or Android native app | Mobile SDK | Mobile Key | +| React Native, Flutter | Mobile SDK | Mobile Key | +| Electron desktop app | Client-side SDK (Node.js) | Client-side ID | +| Cloudflare Workers, Vercel Edge, AWS Lambda@Edge | Edge SDK | SDK Key | +| .NET client (MAUI, Xamarin, WPF, UWP) | Client-side SDK (.NET) | Mobile Key | +| C/C++ client application | Client-side SDK (C/C++) | Mobile Key | +| C/C++ server application | Server-side SDK (C/C++) | SDK Key | +| Haskell server | Server-side SDK (Haskell) | SDK Key | +| Lua server | Server-side SDK (Lua) | SDK Key | +| Roku (BrightScript) | Client-side SDK (Roku) | Mobile Key | + +For a complete list of SDKs, see: +- Server-side: https://launchdarkly.com/docs/sdk/server-side +- Client-side: https://launchdarkly.com/docs/sdk/client-side +- Edge: https://launchdarkly.com/docs/sdk/edge + +**Important distinctions:** +- **Next.js**: Use server-side SDK for API routes/server components, React client SDK for client components. Start with whichever matches the user's primary use case. +- **Node.js**: If it's a backend service (Express, Fastify, etc.), use the server-side SDK. There is also a [Node.js client SDK](https://launchdarkly.com/docs/sdk/client-side/node-js) for desktop/Electron apps. +- **React**: If it's a standalone SPA, use `launchdarkly-react-client-sdk`. If it's part of Next.js, see above. +- **.NET**: Use the server SDK for ASP.NET/backend services. Use the client SDK for MAUI, Xamarin, WPF, or UWP apps. + +## Plan the Changes + +Your integration plan should identify exactly: + +### 1. Files to Modify + +Use the information gathered during the [Detect step](1.0-detect.md) — specifically the detected package manager, dependency file, and application entrypoint: + +- **Dependency file**: The file identified during detection (e.g., `package.json`, `requirements.txt`, `go.mod`) — use the detected package manager to add the SDK +- **Entrypoint file**: The application entrypoint identified during detection — where SDK initialization code will go +- **Environment/config file**: `.env`, `.env.example`, or equivalent (for the SDK key) — follow the project's existing configuration pattern + +### 2. Code Changes + +For each file, describe the specific change: + +1. **Add SDK dependency** — the install command from the SDK recipe +2. **Add SDK import** — the import statement at the top of the entrypoint +3. **Add SDK initialization** — the init code, placed early in the application startup +4. **Configure the SDK key** — via environment variable, never hardcoded + +### 3. Environment Variable Convention + +Check how the project handles configuration: +- Does it use `.env` files? Add `LAUNCHDARKLY_SDK_KEY` (or `LAUNCHDARKLY_CLIENT_SIDE_ID` for client SDKs) +- Does it use a config module? Add the key there +- Does it read from process.env directly? Follow that pattern + +If a `.env.example` or `.env.sample` exists, plan to add the variable there too (with a placeholder value). + +## Present the Plan + +Before making any changes, summarize the plan to the user: + +``` +Integration Plan: +- SDK: [SDK name] ([server/client/mobile]-side) +- Package: [package name] +- Install: [install command] +- Files to change: + 1. [dependency file] — add SDK dependency + 2. [entrypoint file] — add import and initialization + 3. [env file] — add SDK key variable +``` + +Wait for user confirmation before proceeding, especially if: +- Multiple SDKs could apply (ask which one) +- The entrypoint is ambiguous (ask which file) +- The project structure is unusual + +## Status + +``` +[STATUS] Selecting SDK for detected stack +[STATUS] Identifying files to modify +[STATUS] Generating integration plan +``` + +--- + +**Upon completion, continue with:** [Apply Code Changes](1.2-apply.md) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.2-apply.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.2-apply.md new file mode 100644 index 0000000..51796ac --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.2-apply.md @@ -0,0 +1,151 @@ +--- +title: Apply Code Changes +description: Install the SDK dependency and add initialization code to the application entrypoint +--- + +# Apply Code Changes + +Now execute the integration plan. Install the SDK and add the minimal code needed to initialize it. + +## Step 1: Install the SDK Dependency + +Run the install command from the [SDK Recipes](sdk-recipes.md) using the project's package manager. + +**Examples:** +```bash +# Node.js (npm) +npm install @launchdarkly/node-server-sdk --save + +# Python (pip) +pip install launchdarkly-server-sdk + +# Go +go get github.com/launchdarkly/go-server-sdk/v7 + +# Ruby +bundle add launchdarkly-server-sdk + +# .NET +dotnet add package LaunchDarkly.ServerSdk +``` + +After installation, verify the dependency appears in the lock file or dependency manifest. + +## Step 2: Add the SDK Key to Environment Configuration + +**Never hardcode SDK keys in source code.** + +Add the appropriate environment variable: + +| SDK Type | Variable Name | Where to Get It | +|----------|--------------|-----------------| +| Server-side | `LAUNCHDARKLY_SDK_KEY` | LaunchDarkly > Project settings > Environments > SDK key | +| Client-side | `LAUNCHDARKLY_CLIENT_SIDE_ID` | LaunchDarkly > Project settings > Environments > Client-side ID | +| Mobile | `LAUNCHDARKLY_MOBILE_KEY` | LaunchDarkly > Project settings > Environments > Mobile key | + +Add to the project's environment configuration: + +1. If `.env` exists, add the variable there +2. If `.env.example` or `.env.sample` exists, add a placeholder entry +3. If the project uses a config module, add it there following existing patterns + +```bash +# .env +LAUNCHDARKLY_SDK_KEY=your-sdk-key-here +``` + +Tell the user they need to replace the placeholder with their actual key. + +## Step 3: Add SDK Initialization Code + +Add the import and initialization code to the application entrypoint. Place initialization **early** in the startup sequence, before any code that might need feature flags. + +### Key Principles + +1. **Import at the top** of the file with other imports +2. **Initialize early** in the application lifecycle +3. **Wait for initialization** before evaluating flags (most SDKs support this) +4. **Handle errors** — log failures but don't crash the application +5. **Match existing code style** — use the same patterns (async/await, callbacks, error handling) as the rest of the codebase + +### Server-Side Initialization Pattern + +```javascript +// Node.js example +const LaunchDarkly = require('@launchdarkly/node-server-sdk'); + +const ldClient = LaunchDarkly.init(process.env.LAUNCHDARKLY_SDK_KEY); + +// Wait for initialization before serving requests +await ldClient.waitForInitialization(); +console.log('LaunchDarkly SDK initialized successfully'); +``` + +```python +# Python example +import ldclient +from ldclient.config import Config + +ldclient.set_config(Config(os.environ['LAUNCHDARKLY_SDK_KEY'])) +client = ldclient.get() + +if client.is_initialized(): + print('LaunchDarkly SDK initialized successfully') +``` + +```go +// Go example +import ld "github.com/launchdarkly/go-server-sdk/v7" + +ldClient, err := ld.MakeClient(os.Getenv("LAUNCHDARKLY_SDK_KEY"), 5*time.Second) +if err != nil { + log.Printf("LaunchDarkly SDK failed to initialize: %v", err) +} +``` + +### Client-Side Initialization Pattern + +```tsx +// React example +import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk'; + +const LDProvider = await asyncWithLDProvider({ + clientSideID: process.env.REACT_APP_LAUNCHDARKLY_CLIENT_SIDE_ID, + context: { + kind: 'user', + key: 'anonymous', + }, +}); + +// Wrap your app with the provider +root.render( + + + +); +``` + +Refer to the [SDK Recipes](sdk-recipes.md) for language-specific import and init snippets. + +## Step 4: Verify the Code Compiles + +After making changes: + +1. Run the project's build or compile step +2. Run the linter if one is configured +3. Fix any import errors or type issues + +Do not proceed to the next step if the code doesn't compile. + +## Status + +``` +[STATUS] Installing SDK dependency +[STATUS] Configuring SDK key +[STATUS] Adding initialization code +[STATUS] Verifying code compiles +``` + +--- + +**Upon completion, continue with:** [Start the Application](1.3-run.md) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md new file mode 100644 index 0000000..96f9f22 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md @@ -0,0 +1,89 @@ +--- +title: Start the Application +description: Run the application and confirm the LaunchDarkly SDK initializes successfully +--- + +# Start the Application + +After installing the SDK and adding initialization code, verify the application starts and the SDK connects. + +## Step 1: Identify the Run Command + +Find how the project is normally started: + +| Indicator | Run Command | +|-----------|-------------| +| `package.json` `"scripts"."start"` | `npm start` or `npm run dev` | +| `package.json` `"scripts"."dev"` | `npm run dev` | +| `Makefile` with `run` target | `make run` | +| `manage.py` (Django) | `python manage.py runserver` | +| `app.py` or `main.py` (Flask/FastAPI) | `python app.py` or `uvicorn main:app` | +| `go.mod` | `go run .` or `go run cmd/server/main.go` | +| `Gemfile` with Rails | `bin/rails server` | +| `Cargo.toml` | `cargo run` | + +If the project has a README with run instructions, follow those. + +## Step 2: Start the Application + +Run the application. Do NOT rely on specific log messages to determine success — different SDKs log differently and some don't log at all. + +### What to Look For +- The application starts without crashing +- No import errors or module-not-found errors +- The app is responsive (e.g., serves HTTP requests, renders UI) + +### Common Startup Errors +- `Module not found` or `ImportError` — the SDK wasn't installed correctly. Re-run the install command. +- `TypeError` or `undefined` — initialization code may have a syntax issue. Check the code against the SDK recipe. +- Network timeout — the SDK can't reach LaunchDarkly (check firewall/proxy settings). +- App crashes on startup — check if the SDK key environment variable is set. + +**Important**: The SDK may initialize silently. Do not assume failure just because you don't see a success log message. The actual validation happens in the next step using the `sdk-active` endpoint. + +## Step 3: Handle Common Issues + +| Issue | Solution | +|-------|----------| +| SDK key not set | Remind the user to set the `LAUNCHDARKLY_SDK_KEY` environment variable | +| Module not found | Re-run the install command; check the dependency file | +| Initialization timeout | Check network connectivity; verify the SDK key is valid | +| Type errors | Check the import statement matches the SDK version | +| App starts but no SDK log | Verify the initialization code is actually being executed (not behind a conditional) | + +## Step 4: Confirm SDK Activity + +Once the application is running, use the `sdk-active` endpoint to confirm the SDK has connected to LaunchDarkly. This is the definitive check — not log messages. + +Use `ldcli` if available: + +```bash +ldcli sdk-active \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --environment ENVIRONMENT_KEY +``` + +Or call the API directly: + +```bash +curl -s -X GET \ + "https://app.launchdarkly.com/api/v2/projects/PROJECT_KEY/environments/ENVIRONMENT_KEY/sdk-active" \ + -H "Authorization: LAUNCHDARKLY_ACCESS_TOKEN" +``` + +If the SDK is not yet active, wait 30 seconds and retry — the SDK needs to send at least one event to LaunchDarkly before it shows as active. + +If you cannot start the application (e.g., it requires infrastructure the agent doesn't have access to), ask the user to start it manually and confirm it's running. + +## Status + +``` +[STATUS] Identifying run command +[STATUS] Starting application +[STATUS] Checking SDK initialization +``` + +--- + +**Upon completion, continue with:** [Validate SDK Connection](1.4-validate.md) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md new file mode 100644 index 0000000..7fcab25 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md @@ -0,0 +1,99 @@ +--- +title: Validate SDK Connection +description: Confirm that LaunchDarkly sees the SDK connection using the API or MCP +--- + +# Validate SDK Connection + +The application is running — now confirm LaunchDarkly actually sees the SDK connection. This is the critical step that proves the integration works end-to-end. + +## Option A: Validate via ldcli (Preferred) + +The `ldcli sdk-active` command is the fastest way to check if the SDK is connected: + +```bash +ldcli sdk-active \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --environment ENVIRONMENT_KEY +``` + +This checks the LaunchDarkly backend for recent SDK activity in the target environment. + +## Option B: Validate via LaunchDarkly API + +If `ldcli` is not available, use the REST API directly: + +```bash +curl -s -X GET \ + "https://app.launchdarkly.com/api/v2/projects/PROJECT_KEY/environments/ENVIRONMENT_KEY/sdk-active" \ + -H "Authorization: LAUNCHDARKLY_ACCESS_TOKEN" +``` + +Replace: +- `PROJECT_KEY` with the LaunchDarkly project key +- `ENVIRONMENT_KEY` with the environment key (e.g., `test`, `production`) +- `LAUNCHDARKLY_ACCESS_TOKEN` with the API access token + +A successful response means the SDK has connected to LaunchDarkly. + +## Option C: Validate via MCP + +If the LaunchDarkly MCP server is available, use the `get-environment` tool to check the SDK status: + +1. Call `get-environment` with the project key and environment key +2. Look for the SDK-related fields in the response +3. If the environment shows recent SDK activity, the connection is confirmed + +## Option D: Validate via Dashboard + +As a fallback, direct the user to check: + +**https://app.launchdarkly.com/projects/default/flags** + +If the SDK is connected, the flags page will show evaluation data and SDK version information. + +## Interpreting Results + +| Result | Meaning | Next Step | +|--------|---------|-----------| +| SDK active / connected | Integration is working | Continue to [Create First Feature Flag](1.5-first-flag.md) | +| SDK not active | SDK hasn't connected yet | Wait 30 seconds and retry; check the SDK key is correct | +| 401 Unauthorized | Invalid access token | Verify the API access token | +| 404 Not Found | Invalid project or environment key | Verify the project and environment keys | +| Network error | Can't reach LaunchDarkly API | Check internet connectivity | + +## Retry Logic + +The SDK needs to send at least one event to LaunchDarkly before it registers as active. This can take up to 60 seconds after the application starts. + +**Retry strategy:** +1. Wait 15 seconds after the app starts, then check +2. If not active, wait 30 seconds and retry +3. If not active, wait 30 seconds and retry once more +4. **After 3 failed attempts, stop retrying.** Do not loop indefinitely. + +Keep track of what you've already tried. If you've already verified the SDK key, checked the environment, and confirmed the app is running, don't repeat those checks — move to the troubleshooting section. + +## Troubleshooting + +If validation fails after 3 attempts: + +1. **Verify the SDK key**: Make sure you're using the right key type (SDK key for server-side, Client-side ID for client-side, Mobile key for mobile) +2. **Verify the environment**: Make sure the SDK key matches the environment you're validating against +3. **Check the application logs**: Look for any SDK error messages +4. **Check network**: The SDK needs outbound HTTPS access to `events.launchdarkly.com` and `stream.launchdarkly.com` +5. **Check if the app is actually running**: The sdk-active endpoint requires the app to be running and to have sent at least one event. If the app hasn't started or crashed, fix that first. + +If none of the above works, proceed to [Recovery Procedures](1.6-recover.md). + +## Status + +``` +[STATUS] Validating SDK connection +[STATUS] Checking LaunchDarkly API for SDK activity +``` + +--- + +**Upon completion, continue with:** [Create First Feature Flag](1.5-first-flag.md) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md new file mode 100644 index 0000000..73e2aa4 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md @@ -0,0 +1,194 @@ +--- +title: Create Your First Feature Flag +description: Create a boolean feature flag, add evaluation code, and toggle it to demonstrate end-to-end functionality +--- + +# Create Your First Feature Flag + +The SDK is connected. Now help the user create their first feature flag and see it work end-to-end. + +## Step 1: Create the Flag + +### Via MCP (Preferred) + +If the LaunchDarkly MCP server is available, use `create-flag`: + +- **Key**: `my-first-flag` (or a name relevant to the user's project) +- **Name**: "My First Flag" +- **Kind**: `boolean` +- **Variations**: `true` / `false` +- **Temporary**: `true` + +### Via LaunchDarkly API + +```bash +curl -s -X POST \ + "https://app.launchdarkly.com/api/v2/flags/PROJECT_KEY" \ + -H "Authorization: LAUNCHDARKLY_ACCESS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "My First Flag", + "key": "my-first-flag", + "kind": "boolean", + "variations": [ + {"value": true}, + {"value": false} + ], + "temporary": true + }' +``` + +### Via ldcli + +```bash +ldcli flags create \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --data '{"name": "My First Flag", "key": "my-first-flag", "kind": "boolean"}' +``` + +After creation, the flag starts with **targeting OFF**, serving the off variation (`false`) to everyone. + +## Step 2: Add Flag Evaluation Code + +Add code to evaluate the flag in the application. Place this where it makes sense for the user's feature. + +### Server-Side Examples + +```javascript +// Node.js +const context = { kind: 'user', key: 'example-user-key', name: 'Example User' }; +const showFeature = await ldClient.variation('my-first-flag', context, false); + +if (showFeature) { + console.log('Feature is ON'); +} else { + console.log('Feature is OFF'); +} +``` + +```python +# Python +context = Context.builder("example-user-key").name("Example User").build() +show_feature = client.variation("my-first-flag", context, False) + +if show_feature: + print("Feature is ON") +else: + print("Feature is OFF") +``` + +```go +// Go +context := ldcontext.NewBuilder("example-user-key").Name("Example User").Build() +showFeature, _ := ldClient.BoolVariation("my-first-flag", context, false) + +if showFeature { + fmt.Println("Feature is ON") +} else { + fmt.Println("Feature is OFF") +} +``` + +### Client-Side Examples + +```tsx +// React +import { useFlags } from 'launchdarkly-react-client-sdk'; + +function MyComponent() { + const { myFirstFlag } = useFlags(); + + return ( +
+ {myFirstFlag ?

Feature is ON

:

Feature is OFF

} +
+ ); +} +``` + +**Note**: Client-side React SDK camelCases flag keys, so `my-first-flag` becomes `myFirstFlag`. + +## Step 3: Verify the Default Value + +With targeting OFF, the flag should evaluate to `false`. Run the application and confirm: + +``` +Feature is OFF +``` + +## Step 4: Toggle the Flag On + +### Via MCP + +Use the `toggle-flag` tool to enable the flag in the target environment. + +### Via LaunchDarkly API + +```bash +curl -s -X PATCH \ + "https://app.launchdarkly.com/api/v2/flags/PROJECT_KEY/my-first-flag" \ + -H "Authorization: LAUNCHDARKLY_ACCESS_TOKEN" \ + -H "Content-Type: application/json; domain-model=launchdarkly.semanticpatch" \ + -d '{ + "environmentKey": "ENVIRONMENT_KEY", + "instructions": [ + {"kind": "turnFlagOn"} + ] + }' +``` + +### Via ldcli + +```bash +ldcli flags toggle-on \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --environment ENVIRONMENT_KEY \ + --flag my-first-flag +``` + +## Step 5: Verify the Toggle + +After toggling the flag on, the application should now show: + +``` +Feature is ON +``` + +For server-side SDKs using streaming (the default), the change should be reflected within seconds. For client-side SDKs, the change appears on the next page load or when the SDK polls for updates. + +## Congratulations + +The user has successfully: +1. Installed the LaunchDarkly SDK +2. Connected it to LaunchDarkly +3. Created a feature flag +4. Evaluated it in code +5. Toggled it and seen the result + +## Error Handling + +If any step returns an authorization error (401 or 403): + +1. **Check if the user is logged in**: The access token may be expired or invalid. +2. **Prompt the user to log in**: Direct them to `ldcli login` or https://app.launchdarkly.com to sign in. +3. **If the user doesn't have an account**: Prompt them to sign up at https://launchdarkly.com. +4. **If the project or environment doesn't exist**: Guide the user to create one via the dashboard or `ldcli`. + +Do not retry authorization errors automatically — they require user action. + +**Next steps to suggest:** +- Use the [flag create skill](../../feature-flags/launchdarkly-flag-create/SKILL.md) to create flags that fit the codebase's patterns +- Use the [flag targeting skill](../../feature-flags/launchdarkly-flag-targeting/SKILL.md) to set up percentage rollouts and targeting rules +- Read the [LaunchDarkly docs](https://docs.launchdarkly.com) for advanced topics like contexts, experimentation, and metrics + +## Status + +``` +[STATUS] Creating feature flag +[STATUS] Adding flag evaluation code +[STATUS] Verifying flag evaluates to default +[STATUS] Toggling flag on +[STATUS] Verifying flag toggle works +``` diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.6-recover.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.6-recover.md new file mode 100644 index 0000000..81cdaf6 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.6-recover.md @@ -0,0 +1,110 @@ +--- +title: Recovery Procedures +description: Diagnose failures and resume the onboarding workflow with ranked recovery options +--- + +# Recovery Procedures + +When any step in the onboarding workflow fails, use this guide to diagnose the issue and get back on track. + +## Step 1: Identify the Failure + +Note which step failed and the specific error: + +| Failed Step | Common Errors | +|-------------|---------------| +| Detect | Unable to identify language or framework | +| Plan | Multiple SDKs could apply; ambiguous stack | +| Apply | Install command failed; import errors; code doesn't compile | +| Run | Application won't start; SDK initialization error | +| Validate | SDK not showing as active; API errors | +| First Flag | Flag creation failed; evaluation returns unexpected value | + +## Step 2: Choose a Recovery Action + +Recovery options are listed in priority order. Start with option 1 and work down. + +### Option 1: Retry Current Step + +Re-attempt the failed step after reviewing the error output. Many issues are transient (network timeouts, temporary API errors) or are fixed by correcting a small mistake. + +### Option 2: Verify Credentials + +Confirm the LaunchDarkly access token and SDK key are valid: + +```bash +# Test API access +curl -s -X GET \ + "https://app.launchdarkly.com/api/v2/projects" \ + -H "Authorization: YOUR_ACCESS_TOKEN" +``` + +Or via ldcli: +```bash +ldcli environments list --project PROJECT_KEY --access-token YOUR_ACCESS_TOKEN +``` + +If this fails with 401, the token is invalid or expired. Ask the user to provide a valid token. + +### Option 3: Check Network Connectivity + +The SDK needs outbound HTTPS access to: +- `app.launchdarkly.com` (API) +- `stream.launchdarkly.com` (streaming) +- `events.launchdarkly.com` (events) + +Test connectivity: +```bash +curl -s -o /dev/null -w "%{http_code}" https://app.launchdarkly.com/api/v2 +``` + +If the network is blocked, advise the user to check firewall rules and proxy settings. + +### Option 4: Manual SDK Install + +If automatic dependency installation fails, provide the user with copy/paste instructions: + +1. Show the exact package name and version from the [SDK Recipes](sdk-recipes.md) +2. Provide the manual install command +3. Ask the user to run it themselves and confirm completion + +### Option 5: Try Alternative SDK + +If the detected SDK was wrong: + +1. Ask the user what language/framework they're targeting +2. Let them manually select from the [SDK Recipes](sdk-recipes.md) +3. Restart from the Plan step with the correct SDK + +### Option 6: Skip to Next Step + +If the failure is non-critical, skip ahead: + +- **Can't auto-run the app?** Ask the user to start it manually, then continue to Validate +- **Can't validate via API?** Ask the user to check the LaunchDarkly dashboard +- **Can't create a flag programmatically?** Walk the user through creating it in the dashboard + +### Option 7: Abort Onboarding + +If the issue can't be resolved: + +1. Summarize what was accomplished (which steps succeeded) +2. Provide links for manual setup: + - [LaunchDarkly SDK documentation](https://docs.launchdarkly.com/sdk) + - [LaunchDarkly getting started guide](https://docs.launchdarkly.com/home/getting-started) +3. Suggest the user reach out to LaunchDarkly support + +## Automatic Escalation + +If the same step fails **3 times**, automatically suggest: +- Skipping the step (if non-critical) +- Aborting and providing manual instructions +- Asking the user for help with the specific error + +## Status + +``` +[STATUS] Diagnosing failure in step: [step name] +[STATUS] Attempting recovery: [recovery option] +[STATUS] Resuming workflow from step: [step name] +``` diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.7-mcp-setup.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.7-mcp-setup.md new file mode 100644 index 0000000..78a8757 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.7-mcp-setup.md @@ -0,0 +1,119 @@ +--- +title: MCP Server Setup +description: Guide the user through installing and configuring the LaunchDarkly MCP server for enhanced agent workflows +--- + +# MCP Server Setup + +After the SDK is integrated and the first flag is working, offer to set up the LaunchDarkly MCP server. This enables richer agent-driven workflows like flag management, targeting, and experimentation directly from the editor. + +## Step 1: Check if MCP Server is Already Installed + +Look for `@launchdarkly/mcp-server` in the user's MCP configuration: + +- **Cursor**: Check `.cursor/mcp.json` or the Cursor settings UI +- **VS Code / Copilot**: Check `.vscode/mcp.json` or the MCP settings +- **Claude Desktop**: Check `claude_desktop_config.json` +- **Other agents**: Check the agent's MCP server configuration + +If already installed, skip this step and congratulate the user — they're all set. + +## Step 2: Ask the User + +If the MCP server is not installed, ask: + +> "Would you like to install the LaunchDarkly MCP server? It lets your AI agent create and manage feature flags, set up targeting rules, and more — all without leaving your editor." + +If the user declines, skip to the end. The SDK integration is complete without it. + +## Step 3: Install the MCP Server + +### For Cursor + +Add to `.cursor/mcp.json`: + +```json +{ + "mcpServers": { + "launchdarkly": { + "command": "npx", + "args": ["-y", "@launchdarkly/mcp-server"], + "env": { + "LAUNCHDARKLY_ACCESS_TOKEN": "YOUR_ACCESS_TOKEN" + } + } + } +} +``` + +### For Claude Desktop + +Add to `claude_desktop_config.json`: + +```json +{ + "mcpServers": { + "launchdarkly": { + "command": "npx", + "args": ["-y", "@launchdarkly/mcp-server"], + "env": { + "LAUNCHDARKLY_ACCESS_TOKEN": "YOUR_ACCESS_TOKEN" + } + } + } +} +``` + +### For VS Code / Copilot + +Add to `.vscode/mcp.json`: + +```json +{ + "servers": { + "launchdarkly": { + "command": "npx", + "args": ["-y", "@launchdarkly/mcp-server"], + "env": { + "LAUNCHDARKLY_ACCESS_TOKEN": "YOUR_ACCESS_TOKEN" + } + } + } +} +``` + +Replace `YOUR_ACCESS_TOKEN` with the user's LaunchDarkly API access token. If they already used one during the onboarding flow, suggest reusing it. + +## Step 4: Verify the MCP Server + +After configuring: + +1. Restart the editor or reload the MCP configuration +2. Ask the user to try a command like "list my feature flags" to verify the MCP server is connected +3. If it works, the setup is complete + +## What the MCP Server Enables + +With the MCP server installed, agents can: + +- Create and manage feature flags +- Configure targeting rules and percentage rollouts +- Toggle flags on/off across environments +- View flag status and evaluation insights +- Manage AI configs and experiments + +## Status + +``` +[STATUS] Checking for existing MCP server installation +[STATUS] Offering MCP server setup +[STATUS] Configuring MCP server +[STATUS] Verifying MCP server connection +``` + +--- + +**Onboarding complete!** The user now has: +1. A LaunchDarkly SDK integrated into their project +2. A working feature flag they can toggle +3. (Optionally) The MCP server for ongoing flag management diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md new file mode 100644 index 0000000..ca4e9c0 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md @@ -0,0 +1,146 @@ +--- +title: Onboarding Summary +description: Generate a setup summary document the user can reference, with links to documentation and suggested next steps +--- + +# Onboarding Summary + +After completing the onboarding flow, leave behind a summary document in the user's repository so they (and their team) have a reference for how LaunchDarkly was set up and what to do next. + +## Step 1: Generate the Summary Document + +Create a file called `LAUNCHDARKLY.md` (or `docs/LAUNCHDARKLY.md` if the project has a `docs/` directory) in the user's repository with the following sections. Fill in the details based on what was done during onboarding. + +### Template + +```markdown +# LaunchDarkly Setup + +This project uses [LaunchDarkly](https://launchdarkly.com) for feature flag management. + +## SDK Details + +- **SDK**: {SDK_NAME} ({SDK_PACKAGE}) +- **SDK Type**: {server-side | client-side | mobile | edge} +- **Key Type**: {SDK Key | Client-side ID | Mobile Key} +- **Installed via**: {INSTALL_COMMAND} +- **Initialization file**: {ENTRYPOINT_FILE} + +## Configuration + +The SDK key is configured via the `{ENV_VAR_NAME}` environment variable. + +- **Do not hardcode** the SDK key in source code. +- Add the key to your `.env` file locally (already in `.gitignore`). +- For production, set it in your deployment environment (e.g., CI/CD secrets, container env vars, cloud config). + +## Where to Find Things + +| What | Where | +|------|-------| +| Feature flags dashboard | https://app.launchdarkly.com/projects/{PROJECT_KEY}/flags | +| Project settings | https://app.launchdarkly.com/settings/projects/{PROJECT_KEY} | +| Environments | https://app.launchdarkly.com/settings/projects/{PROJECT_KEY}/environments | +| API access tokens | https://app.launchdarkly.com/settings/authorization | +| SDK documentation | {SDK_DOCS_URL} | +| LaunchDarkly docs | https://launchdarkly.com/docs | + +## How Feature Flags Work in This Project + +1. Flags are evaluated using the LaunchDarkly SDK in `{ENTRYPOINT_FILE}` +2. Flag values are fetched from LaunchDarkly based on the evaluation context (user/device/org) +3. Changes to flags in the dashboard take effect immediately (server-side SDKs use streaming by default) + +### Example: Evaluating a Flag + +{INSERT_LANGUAGE_SPECIFIC_EXAMPLE} + +## Next Steps + +Here are some things you can do now that LaunchDarkly is set up: + +### Feature Flag Best Practices +- **Use flags for every new feature**: Wrap new features in flags so you can release and roll back independently of deployments. +- **Clean up temporary flags**: Mark flags as temporary during creation and archive them when no longer needed. +- **Use descriptive flag keys**: e.g., `enable-checkout-v2` instead of `flag-1`. + +### Advanced Capabilities +- **[Percentage Rollouts](https://launchdarkly.com/docs/home/targeting-flags/rollouts)** — Gradually roll out features to a percentage of users. +- **[Targeting Rules](https://launchdarkly.com/docs/home/targeting-flags/targeting-rules)** — Target specific users, segments, or contexts. +- **[Experimentation](https://launchdarkly.com/docs/home/about-experimentation)** — Run A/B tests and measure the impact of flag variations. +- **[AI Configs](https://launchdarkly.com/docs/home/ai-configs)** — Manage AI model configurations and prompts with feature flags. +- **[Guarded Rollouts](https://launchdarkly.com/docs/home/guarded-rollouts)** — Automatically roll back flag changes based on metric guardrails. +- **[Observability](https://launchdarkly.com/docs/home/observability)** — Monitor flag evaluations and SDK performance with built-in telemetry. + +### AI Agent Integration (MCP Server) + +Install the [LaunchDarkly MCP server](https://github.com/launchdarkly/mcp-server) to let your AI agent manage feature flags directly from your editor. With it, your agent can: + +- **Create and manage flags** — Ask your agent to create a new feature flag, and it will handle the API calls for you. +- **Toggle flags on/off** — Turn features on or off across environments without leaving your editor. +- **Set up targeting rules** — Configure percentage rollouts, user targeting, and segment-based rules through natural language. +- **Clean up stale flags** — Ask your agent to find temporary flags that are fully rolled out and ready to archive. +- **Run experiments** — Set up A/B tests and monitor results through your agent. +- **Manage AI configs** — Update model configurations and prompts managed by LaunchDarkly. + +To install, add to your editor's MCP configuration: + +```json +{ + "mcpServers": { + "launchdarkly": { + "command": "npx", + "args": ["-y", "@launchdarkly/mcp-server"], + "env": { + "LAUNCHDARKLY_ACCESS_TOKEN": "YOUR_ACCESS_TOKEN" + } + } + } +} +``` + +See the [MCP server docs](https://github.com/launchdarkly/mcp-server) for editor-specific setup instructions. + +### Useful CLI Commands + +If you have `ldcli` installed: + +| Command | Description | +|---------|-------------| +| `ldcli flags list --project {PROJECT_KEY}` | List all feature flags | +| `ldcli flags toggle-on --project {PROJECT_KEY} --environment {ENV_KEY} --flag FLAG_KEY` | Turn a flag on | +| `ldcli flags create --project {PROJECT_KEY} --data '{"name": "My Flag", "key": "my-flag", "kind": "boolean"}'` | Create a new flag | +| `ldcli sdk-active --project {PROJECT_KEY} --environment {ENV_KEY}` | Check if the SDK is connected | +``` + +## Step 2: Fill in the Template + +Replace all `{PLACEHOLDER}` values with the actual values from the onboarding session: + +- `{SDK_NAME}`: The human-readable SDK name (e.g., "Node.js Server SDK") +- `{SDK_PACKAGE}`: The package name (e.g., `@launchdarkly/node-server-sdk`) +- `{INSTALL_COMMAND}`: The install command used (e.g., `npm install @launchdarkly/node-server-sdk`) +- `{ENTRYPOINT_FILE}`: The file where initialization code was added +- `{ENV_VAR_NAME}`: The environment variable name used for the SDK key +- `{PROJECT_KEY}`: The LaunchDarkly project key +- `{ENV_KEY}`: The LaunchDarkly environment key +- `{SDK_DOCS_URL}`: Link to the specific SDK documentation +- `{INSERT_LANGUAGE_SPECIFIC_EXAMPLE}`: A short code snippet showing flag evaluation in the project's language + +## Step 3: Commit the Summary + +Add the file to version control so the whole team can reference it: + +```bash +git add LAUNCHDARKLY.md +git commit -m "docs: add LaunchDarkly setup reference" +``` + +Ask the user for permission before committing. If they prefer not to commit it, that's fine — they still have the file locally. + +## Status + +``` +[STATUS] Generating onboarding summary document +[STATUS] Writing LAUNCHDARKLY.md +``` diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md new file mode 100644 index 0000000..95f812a --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md @@ -0,0 +1,158 @@ +--- +title: Editor Rules and Skills +description: Leave behind editor-specific rules and skills for ongoing LaunchDarkly feature flag management +--- + +# Editor Rules and Skills + +After onboarding is complete, install editor-specific rules so the user's AI agent has LaunchDarkly skills available for ongoing feature flag management. Detect which editor the user is using and create the appropriate rules file. + +## Step 1: Detect the Editor + +Check for editor configuration files in the project root: + +| File/Directory | Editor | +|---------------|--------| +| `.cursor/` or `.cursorrules` | Cursor | +| `.claude/` | Claude Code (Anthropic) | +| `.github/copilot-instructions.md` | GitHub Copilot | +| `.vscode/` (without Cursor indicators) | VS Code | +| `.idea/` | JetBrains IDE | + +If you can't detect the editor, default to Claude Code and create `.claude/rules/launchdarkly.md`. + +## Step 2: Create the Rules File + +Based on the detected editor, create the appropriate rules file with LaunchDarkly feature flag management skills. + +### For Cursor (`.cursor/rules/launchdarkly.mdc`) + +Create `.cursor/rules/launchdarkly.mdc`: + +```markdown +--- +description: LaunchDarkly feature flag management rules +globs: +alwaysApply: false +--- + +# LaunchDarkly Feature Flags + +This project uses LaunchDarkly for feature flag management. + +## SDK Details +- SDK: {SDK_NAME} +- Initialization: {ENTRYPOINT_FILE} +- Key env var: {ENV_VAR_NAME} + +## Rules + +### Creating Feature Flags +- Always wrap new features in a LaunchDarkly feature flag +- Use descriptive, kebab-case flag keys (e.g., `enable-checkout-v2`) +- Mark flags as `temporary: true` if they're for a short-lived rollout +- Default to boolean flags unless you need multivariate (string/number/JSON) + +### Evaluating Flags +- Always provide a fallback/default value when evaluating flags +- Use a meaningful evaluation context (user key, email, org, etc.) +- For React components, use the `useFlags()` hook from the LaunchDarkly React SDK +- Never evaluate flags in a tight loop — cache the result if needed + +### Flag Hygiene +- Archive flags that are no longer needed +- Remove flag evaluation code when a flag is permanently rolled out +- Keep flag keys consistent across environments + +### SDK Key Safety +- Never hardcode SDK keys — always use environment variables +- The SDK key for this project is stored in `{ENV_VAR_NAME}` +- Server-side SDK keys are secret; client-side IDs are safe to expose in browser code + +### Agent Skills for Feature Flags +Use these LaunchDarkly agent skills for common flag operations: +- **[Flag Create](https://github.com/launchdarkly/agent-skills/tree/main/skills/feature-flags/launchdarkly-flag-create)** — Create new feature flags with the right configuration +- **[Flag Targeting](https://github.com/launchdarkly/agent-skills/tree/main/skills/feature-flags/launchdarkly-flag-targeting)** — Set up targeting rules, percentage rollouts, and user segments +- **[Flag Cleanup](https://github.com/launchdarkly/agent-skills/tree/main/skills/feature-flags/launchdarkly-flag-cleanup)** — Find and archive stale or fully-rolled-out flags +- **[Flag Discovery](https://github.com/launchdarkly/agent-skills/tree/main/skills/feature-flags/launchdarkly-flag-discovery)** — Explore existing flags, their status, and usage + +### Available Tools +If the LaunchDarkly MCP server is installed, you can: +- Create and manage feature flags +- Toggle flags on/off +- Set up targeting rules and percentage rollouts +- View flag status and evaluation insights + +### Documentation +- SDK docs: {SDK_DOCS_URL} +- Feature flags: https://launchdarkly.com/docs/home/flags +- Targeting: https://launchdarkly.com/docs/home/targeting-flags +- Experimentation: https://launchdarkly.com/docs/home/about-experimentation +``` + +### For Claude Code (`.claude/rules/launchdarkly.md`) + +Create `.claude/rules/launchdarkly.md` with the same content as above (without the YAML frontmatter header — use plain markdown): + +```markdown +# LaunchDarkly Feature Flags + +This project uses LaunchDarkly for feature flag management. + +## SDK Details +- SDK: {SDK_NAME} +- Initialization: {ENTRYPOINT_FILE} +- Key env var: {ENV_VAR_NAME} + +## Rules +{SAME_RULES_AS_ABOVE} +``` + +### For GitHub Copilot (`.github/copilot-instructions.md`) + +Append to `.github/copilot-instructions.md` (create if it doesn't exist): + +```markdown +## LaunchDarkly Feature Flags + +This project uses LaunchDarkly ({SDK_NAME}) for feature flag management. +Flag evaluation is initialized in {ENTRYPOINT_FILE}. + +When creating new features: +- Wrap new features in LaunchDarkly feature flags +- Use descriptive kebab-case flag keys (e.g., `enable-checkout-v2`) +- Always provide a fallback value when evaluating flags +- Never hardcode SDK keys — use the {ENV_VAR_NAME} environment variable + +SDK docs: {SDK_DOCS_URL} +``` + +### For Other Editors + +If the editor doesn't have a rules system, skip this step. The `LAUNCHDARKLY.md` summary document serves as the reference instead. + +## Step 3: Fill in the Placeholders + +Replace all `{PLACEHOLDER}` values with actual values from the onboarding session: + +- `{SDK_NAME}`: e.g., "Node.js Server SDK" +- `{ENTRYPOINT_FILE}`: e.g., `src/index.ts` +- `{ENV_VAR_NAME}`: e.g., `LAUNCHDARKLY_SDK_KEY` +- `{SDK_DOCS_URL}`: e.g., `https://launchdarkly.com/docs/sdk/server-side/node-js` + +## Step 4: Commit the Rules + +```bash +git add .cursor/rules/launchdarkly.mdc # or the appropriate file +git commit -m "chore: add LaunchDarkly feature flag management rules" +``` + +Ask the user for permission before committing. + +## Status + +``` +[STATUS] Detecting user's editor +[STATUS] Creating editor-specific rules file +[STATUS] Committing rules to repository +``` diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md new file mode 100644 index 0000000..8ef3ddb --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md @@ -0,0 +1,500 @@ +--- +title: SDK Recipes +description: Detection patterns, install commands, import statements, and initialization snippets for all LaunchDarkly SDKs +--- + +# SDK Recipes + +Use this reference to match a detected tech stack to the correct LaunchDarkly SDK. Each recipe includes detection patterns, install commands, and initialization code. + +> **Canonical source**: The `ldcli` CLI contains per-SDK instruction files at +> [`internal/sdks/sdk_instructions/`](https://github.com/launchdarkly/ldcli/tree/main/internal/sdks/sdk_instructions). +> If a recipe below seems outdated, cross-reference those files or run `ldcli setup` for the latest guidance. + +## Server-Side SDKs + +Server-side SDKs use an **SDK Key** and are designed for backend services where the key can be kept secret. + +### Node.js (Server) + +| Field | Value | +|-------|-------| +| Package | `@launchdarkly/node-server-sdk` | +| Detect files | `package.json` | +| Detect patterns | `express`, `fastify`, `koa`, `hapi`, `nestjs`, `next` (API routes), `"type": "module"` | +| Install | `npm install @launchdarkly/node-server-sdk --save` | + +```javascript +// Import +const LaunchDarkly = require('@launchdarkly/node-server-sdk'); + +// Initialize +const ldClient = LaunchDarkly.init(process.env.LAUNCHDARKLY_SDK_KEY); +await ldClient.waitForInitialization(); + +// Evaluate +const context = { kind: 'user', key: 'user-key-123' }; +const flagValue = await ldClient.variation('flag-key', context, false); +``` + +### Python (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-server-sdk` | +| Detect files | `requirements.txt`, `pyproject.toml`, `setup.py`, `Pipfile` | +| Detect patterns | `flask`, `django`, `fastapi`, `starlette` | +| Install | `pip install launchdarkly-server-sdk` | + +```python +# Import +import ldclient +from ldclient import Context +from ldclient.config import Config + +# Initialize +ldclient.set_config(Config(os.environ['LAUNCHDARKLY_SDK_KEY'])) +client = ldclient.get() + +# Evaluate +context = Context.builder("user-key-123").name("User").build() +flag_value = client.variation("flag-key", context, False) +``` + +### Go (Server) + +| Field | Value | +|-------|-------| +| Package | `github.com/launchdarkly/go-server-sdk/v7` | +| Detect files | `go.mod`, `go.sum` | +| Detect patterns | `net/http`, `gin`, `echo`, `fiber`, `chi` | +| Install | `go get github.com/launchdarkly/go-server-sdk/v7` | + +```go +// Import +import ( + ld "github.com/launchdarkly/go-server-sdk/v7" + "github.com/launchdarkly/go-sdk-common/v3/ldcontext" +) + +// Initialize +ldClient, err := ld.MakeClient(os.Getenv("LAUNCHDARKLY_SDK_KEY"), 5*time.Second) + +// Evaluate +context := ldcontext.NewBuilder("user-key-123").Name("User").Build() +flagValue, _ := ldClient.BoolVariation("flag-key", context, false) +``` + +### Java (Server) + +| Field | Value | +|-------|-------| +| Package | `com.launchdarkly:launchdarkly-java-server-sdk` | +| Detect files | `pom.xml`, `build.gradle`, `build.gradle.kts` | +| Detect patterns | `spring`, `quarkus`, `micronaut`, `dropwizard` | +| Install | Add `com.launchdarkly:launchdarkly-java-server-sdk` to your build file | + +```java +// Import +import com.launchdarkly.sdk.*; +import com.launchdarkly.sdk.server.*; + +// Initialize +LDClient client = new LDClient(System.getenv("LAUNCHDARKLY_SDK_KEY")); + +// Evaluate +LDContext context = LDContext.builder("user-key-123").name("User").build(); +boolean flagValue = client.boolVariation("flag-key", context, false); +``` + +### Ruby (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-server-sdk` | +| Detect files | `Gemfile`, `*.gemspec` | +| Detect patterns | `rails`, `sinatra`, `hanami` | +| Install | `gem install launchdarkly-server-sdk` or add to Gemfile | + +```ruby +# Import +require 'ldclient-rb' + +# Initialize +client = LaunchDarkly::LDClient.new(ENV['LAUNCHDARKLY_SDK_KEY']) + +# Evaluate +context = LaunchDarkly::LDContext.create({ kind: 'user', key: 'user-key-123', name: 'User' }) +flag_value = client.variation('flag-key', context, false) +``` + +### .NET (Server) + +| Field | Value | +|-------|-------| +| Package | `LaunchDarkly.ServerSdk` | +| Detect files | `*.csproj`, `*.sln`, `*.fsproj` | +| Detect patterns | `Microsoft.AspNetCore`, `Microsoft.NET` | +| Install | `dotnet add package LaunchDarkly.ServerSdk` | + +```csharp +// Import +using LaunchDarkly.Sdk; +using LaunchDarkly.Sdk.Server; + +// Initialize +var client = new LdClient(Environment.GetEnvironmentVariable("LAUNCHDARKLY_SDK_KEY")); + +// Evaluate +var context = Context.Builder("user-key-123").Name("User").Build(); +var flagValue = client.BoolVariation("flag-key", context, false); +``` + +### PHP (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly/server-sdk` | +| Detect files | `composer.json` | +| Detect patterns | `laravel`, `symfony`, `slim` | +| Install | `composer require launchdarkly/server-sdk` | + +```php +// Import +use LaunchDarkly\LDClient; + +// Initialize +$client = new LDClient(getenv('LAUNCHDARKLY_SDK_KEY')); + +// Evaluate +$context = LDContext::builder('user-key-123')->name('User')->build(); +$flagValue = $client->variation('flag-key', $context, false); +``` + +### Rust (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-server-sdk` | +| Detect files | `Cargo.toml` | +| Detect patterns | `actix`, `rocket`, `axum`, `warp` | +| Install | `cargo add launchdarkly-server-sdk` | + +```rust +// Import +use launchdarkly_server_sdk::{Client, ConfigBuilder, ContextBuilder}; + +// Initialize +let config = ConfigBuilder::new(&std::env::var("LAUNCHDARKLY_SDK_KEY").unwrap()).build(); +let client = Client::build(config).expect("Failed to create client"); +client.start_with_default_executor(); + +// Evaluate +let context = ContextBuilder::new("user-key-123").name("User").build().unwrap(); +let flag_value = client.bool_variation(&context, "flag-key", false); +``` + +### Erlang/Elixir (Server) + +| Field | Value | +|-------|-------| +| Package | `ldclient` | +| Detect files | `rebar.config`, `mix.exs` | +| Detect patterns | `erlang`, `elixir`, `phoenix` | +| Install | Add `ldclient` to your `rebar.config` or `mix.exs` dependencies | + +```erlang +%% Initialize +ldclient:start_instance(os:getenv("LAUNCHDARKLY_SDK_KEY")). + +%% Evaluate +Context = ldclient_context:new(<<"user-key-123">>), +FlagValue = ldclient:variation(<<"flag-key">>, Context, false). +``` + +### Haskell (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-server-sdk` | +| Detect files | `*.cabal`, `stack.yaml`, `package.yaml` | +| Detect patterns | `haskell`, `cabal`, `stack` | +| Install | Add `launchdarkly-server-sdk` to your `.cabal` file or `package.yaml` | + +Refer to the [Haskell SDK docs](https://launchdarkly.com/docs/sdk/server-side/haskell) and the [`ldcli` Haskell instructions](https://github.com/launchdarkly/ldcli/blob/main/internal/sdks/sdk_instructions/haskell-server-sdk.md) for initialization code. + +### Lua (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-server-sdk` | +| Detect files | `*.lua`, `*.rockspec` | +| Detect patterns | `lua`, `luarocks` | +| Install | `luarocks install launchdarkly-server-sdk` | + +Refer to the [Lua SDK docs](https://launchdarkly.com/docs/sdk/server-side/lua) and the [`ldcli` Lua instructions](https://github.com/launchdarkly/ldcli/blob/main/internal/sdks/sdk_instructions/lua-server-sdk.md) for initialization code. + +### C++ (Server) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-cpp-server` | +| Detect files | `CMakeLists.txt`, `Makefile`, `*.cpp`, `*.h` | +| Detect patterns | `cmake`, `#include`, server-side C++ patterns | +| Install | Use CMake `FetchContent` or vcpkg to add the SDK | + +Refer to the [C/C++ server SDK docs](https://launchdarkly.com/docs/sdk/server-side/c-c--) and the [`ldcli` C++ server instructions](https://github.com/launchdarkly/ldcli/blob/main/internal/sdks/sdk_instructions/cpp-server-sdk.md) for initialization code. + +--- + +## Client-Side SDKs + +Client-side SDKs use a **Client-side ID** and are designed for browser/frontend applications where the key is visible to users. + +### React + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-react-client-sdk` | +| Detect files | `package.json` | +| Detect patterns | `react`, `react-dom`, `"react":` | +| Install | `npm install launchdarkly-react-client-sdk --save` | + +```tsx +// Import +import { asyncWithLDProvider, useFlags } from 'launchdarkly-react-client-sdk'; + +// Initialize (in app entry) +const LDProvider = await asyncWithLDProvider({ + clientSideID: process.env.REACT_APP_LAUNCHDARKLY_CLIENT_SIDE_ID, + context: { kind: 'user', key: 'anonymous' }, +}); + +// Wrap app + + +// Evaluate (in component) +const { myFlagKey } = useFlags(); // camelCase access +``` + +**Note:** React SDK converts kebab-case flag keys to camelCase. `my-flag-key` becomes `myFlagKey`. + +### Vue + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-vue-client-sdk` | +| Detect files | `package.json` | +| Detect patterns | `vue`, `"vue":` | +| Install | `npm install launchdarkly-vue-client-sdk --save` | + +```javascript +// Import +import { LDPlugin } from 'launchdarkly-vue-client-sdk'; + +// Initialize +app.use(LDPlugin, { clientSideID: process.env.VUE_APP_LAUNCHDARKLY_CLIENT_SIDE_ID }); +``` + +### JavaScript (Browser) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-js-client-sdk` | +| Detect files | `package.json`, `index.html` | +| Detect patterns | `webpack`, `vite`, `parcel`, `rollup` (without React/Vue/Angular) | +| Install | `npm install launchdarkly-js-client-sdk --save` | + +```javascript +// Import +import * as LDClient from 'launchdarkly-js-client-sdk'; + +// Initialize +const context = { kind: 'user', key: 'anonymous' }; +const client = LDClient.initialize('YOUR_CLIENT_SIDE_ID', context); +await client.waitForInitialization(); + +// Evaluate +const flagValue = client.variation('flag-key', false); +``` + +### .NET (Client) + +| Field | Value | +|-------|-------| +| Package | `LaunchDarkly.ClientSdk` | +| Detect files | `*.csproj`, `*.sln` | +| Detect patterns | `Xamarin`, `MAUI`, `WPF`, `UWP`, `Avalonia` | +| Install | `dotnet add package LaunchDarkly.ClientSdk` | + +```csharp +// Import +using LaunchDarkly.Sdk; +using LaunchDarkly.Sdk.Client; + +// Initialize +var config = Configuration.Builder("YOUR_MOBILE_KEY").Build(); +var context = Context.Builder("user-key-123").Name("User").Build(); +var client = LdClient.Init(config, context, TimeSpan.FromSeconds(5)); + +// Evaluate +var flagValue = client.BoolVariation("flag-key", false); +``` + +### C++ (Client) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-cpp-client` | +| Detect files | `CMakeLists.txt`, `Makefile`, `*.cpp`, `*.h` | +| Detect patterns | `cmake`, `#include`, client-side/desktop C++ patterns | +| Install | Use CMake `FetchContent` or vcpkg to add the SDK | + +Refer to the [C/C++ client SDK docs](https://launchdarkly.com/docs/sdk/client-side/c-c--) and the [`ldcli` C++ client instructions](https://github.com/launchdarkly/ldcli/blob/main/internal/sdks/sdk_instructions/cpp-client-sdk.md) for initialization code. + +### Roku (BrightScript) + +| Field | Value | +|-------|-------| +| Package | `LaunchDarkly Roku SDK` | +| Detect files | `manifest`, `*.brs`, `*.xml` (SceneGraph) | +| Detect patterns | `brightscript`, `roku`, `SceneGraph` | +| Install | Download the SDK and add to your Roku project components | + +Refer to the [Roku SDK docs](https://launchdarkly.com/docs/sdk/client-side/roku) and the [`ldcli` Roku instructions](https://github.com/launchdarkly/ldcli/blob/main/internal/sdks/sdk_instructions/roku.md) for initialization code. + +### Node.js (Client / Electron) + +| Field | Value | +|-------|-------| +| Package | `launchdarkly-node-client-sdk` | +| Detect files | `package.json` | +| Detect patterns | `electron` | +| Install | `npm install launchdarkly-node-client-sdk --save` | + +```javascript +// Import +const LDClient = require('launchdarkly-node-client-sdk'); + +// Initialize +const context = { kind: 'user', key: 'user-key-123' }; +const client = LDClient.initialize('YOUR_CLIENT_SIDE_ID', context); +await client.waitForInitialization(); + +// Evaluate +const flagValue = client.variation('flag-key', false); +``` + +--- + +## Mobile SDKs + +Mobile SDKs use a **Mobile Key** and are designed for native mobile applications. + +### Swift / iOS + +| Field | Value | +|-------|-------| +| Package | `LaunchDarkly` (Swift Package Manager) | +| Detect files | `Package.swift`, `Podfile`, `*.xcodeproj` | +| Detect patterns | `UIKit`, `SwiftUI`, `ios` | +| Install | Add `LaunchDarkly` to `Package.swift` or `Podfile` | + +```swift +// Import +import LaunchDarkly + +// Initialize +var config = LDConfig(mobileKey: ProcessInfo.processInfo.environment["LAUNCHDARKLY_MOBILE_KEY"]!) +let context = try LDContextBuilder(key: "user-key-123").build().get() +LDClient.start(config: config, context: context) + +// Evaluate +let flagValue = LDClient.get()!.boolVariation(forKey: "flag-key", defaultValue: false) +``` + +### Android + +| Field | Value | +|-------|-------| +| Package | `com.launchdarkly:launchdarkly-android-client-sdk` | +| Detect files | `build.gradle`, `build.gradle.kts`, `AndroidManifest.xml` | +| Detect patterns | `android`, `com.android`, `androidx` | +| Install | Add `com.launchdarkly:launchdarkly-android-client-sdk` to `build.gradle` | + +```java +// Import +import com.launchdarkly.sdk.android.*; + +// Initialize +LDConfig config = new LDConfig.Builder() + .mobileKey(BuildConfig.LAUNCHDARKLY_MOBILE_KEY) + .build(); +LDContext context = LDContext.builder("user-key-123").build(); +LDClient.init(application, config, context, 5); + +// Evaluate +boolean flagValue = LDClient.get().boolVariation("flag-key", false); +``` + +### Flutter + +| Field | Value | +|-------|-------| +| Package | `launchdarkly_flutter_client_sdk` | +| Detect files | `pubspec.yaml` | +| Detect patterns | `flutter` | +| Install | `flutter pub add launchdarkly_flutter_client_sdk` | + +```dart +// Import +import 'package:launchdarkly_flutter_client_sdk/launchdarkly_flutter_client_sdk.dart'; + +// Initialize +final config = LDConfig(AutoEnvAttributes.enabled, 'YOUR_MOBILE_KEY'); +final context = LDContextBuilder().kind('user', 'user-key-123').build(); +final client = LDClient(config, context); +await client.start(); + +// Evaluate +final flagValue = await client.boolVariation('flag-key', false); +``` + +### React Native + +| Field | Value | +|-------|-------| +| Package | `@launchdarkly/react-native-client-sdk` | +| Detect files | `package.json` | +| Detect patterns | `react-native` | +| Install | `npm install @launchdarkly/react-native-client-sdk --save` | + +```tsx +// Import +import { LDProvider, useFlags } from '@launchdarkly/react-native-client-sdk'; + +// Initialize (wrap app) + + + + +// Evaluate (in component) +const { myFlagKey } = useFlags(); +``` + +--- + +## Edge SDKs + +Edge SDKs are designed for edge computing platforms. They use an **SDK Key**. + +For edge SDK setup instructions, refer to: +- [Cloudflare SDK](https://launchdarkly.com/docs/sdk/edge/cloudflare) +- [Vercel SDK](https://launchdarkly.com/docs/sdk/edge/vercel) +- [Akamai SDK](https://launchdarkly.com/docs/sdk/edge/akamai) + +| Platform | Detect Pattern | Reference | +|----------|---------------|-----------| +| Cloudflare Workers | `wrangler.toml`, `@cloudflare/workers-types` | [Cloudflare SDK docs](https://launchdarkly.com/docs/sdk/edge/cloudflare) | +| Vercel Edge | `vercel.json` with edge functions, `@vercel/edge` | [Vercel SDK docs](https://launchdarkly.com/docs/sdk/edge/vercel) | +| Akamai EdgeWorkers | `bundle.json`, `edgeworkers` | [Akamai SDK docs](https://launchdarkly.com/docs/sdk/edge/akamai) |