From c58cde1a1981af9fcdba4db9bcf4caf5b32c09cd Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 12:11:38 +0000 Subject: [PATCH 1/5] feat: add SDK onboarding skill for AI-agent-driven LaunchDarkly integration Co-Authored-By: Ari Salem --- README.md | 10 + skills.json | 17 + .../launchdarkly-sdk-onboarding/README.md | 37 ++ .../launchdarkly-sdk-onboarding/SKILL.md | 128 ++++++ .../marketplace.json | 20 + .../references/1.0-detect.md | 96 +++++ .../references/1.1-plan.md | 85 ++++ .../references/1.2-apply.md | 151 +++++++ .../references/1.3-run.md | 72 ++++ .../references/1.4-validate.md | 85 ++++ .../references/1.5-first-flag.md | 183 ++++++++ .../references/1.6-recover.md | 110 +++++ .../references/sdk-recipes.md | 401 ++++++++++++++++++ 13 files changed, 1395 insertions(+) create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/README.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.2-apply.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.6-recover.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md 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..825aad6 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md @@ -0,0 +1,128 @@ +--- +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. + +## Prerequisites + +- A LaunchDarkly account with an API access token (or SDK key) +- A project and environment configured in LaunchDarkly +- Access to the user's codebase (read and write) + +## 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 7: Recover](#step-7-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: 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 | Provide manual install instructions from the SDK recipe | +| 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 +- [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..36996a1 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json @@ -0,0 +1,20 @@ +{ + "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": { + "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..95b0565 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md @@ -0,0 +1,96 @@ +--- +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, 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) | +| `Gemfile` | Ruby (check for Rails, Sinatra) | +| `*.csproj`, `*.sln` | .NET/C# | +| `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 | +| `rebar.config`, `mix.exs` | Erlang/Elixir | + +Read the dependency file to identify the specific framework. For `package.json`, check both `dependencies` and `devDependencies`. + +### 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**: 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` + +### 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? + +## Decision Tree + +After detection: + +- **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 + +## 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..3e8d7b1 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md @@ -0,0 +1,85 @@ +--- +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 | Client-side ID | + +**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. If it's Electron, use the client-side SDK. +- **React**: If it's a standalone SPA, use `launchdarkly-react-client-sdk`. If it's part of Next.js, see above. + +## Plan the Changes + +Your integration plan should identify exactly: + +### 1. Files to Modify + +- **Dependency file**: `package.json`, `requirements.txt`, `go.mod`, etc. (for the SDK dependency) +- **Entrypoint file**: Where SDK initialization code will go +- **Environment/config file**: `.env`, `.env.example`, or equivalent (for the SDK key) + +### 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..2103328 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md @@ -0,0 +1,72 @@ +--- +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 and watch the output for: + +### Success Indicators +- `LaunchDarkly SDK initialized successfully` or similar log message +- No import errors or module-not-found errors +- The application starts and is ready to serve (e.g., "listening on port 3000") + +### Failure Indicators +- `SDK failed to initialize` — likely an invalid SDK key +- `Module not found` or `ImportError` — the SDK wasn't installed correctly +- `TypeError` or `undefined` — initialization code may have a syntax issue +- Network timeout — the SDK can't reach LaunchDarkly (check firewall/proxy) + +## 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 + +If the application starts successfully, look for signs the SDK is connected: + +- SDK initialization log message in the console +- No error messages related to LaunchDarkly +- The application is running and responsive + +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..91b35de --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md @@ -0,0 +1,85 @@ +--- +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 MCP (Preferred) + +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 B: Validate via LaunchDarkly API + +If the MCP server is not available, use the LaunchDarkly REST API: + +```bash +curl -s -X GET \ + "https://app.launchdarkly.com/api/v2/sdk-active/PROJECT_KEY/ENVIRONMENT_KEY" \ + -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 ldcli + +If the `ldcli` CLI is installed: + +```bash +ldcli sdk-active \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --environment ENVIRONMENT_KEY +``` + +## Option D: Validate via Dashboard + +Direct the user to check the LaunchDarkly dashboard: + +1. Go to **https://app.launchdarkly.com** +2. Navigate to the project and environment +3. Check **Settings > Environments** — look for a green "SDK connected" indicator +4. Or create a flag and check if the SDK version appears in the flag's evaluation insights + +## 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 | + +## Troubleshooting + +If validation fails after multiple 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` + +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..9d9cec0 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md @@ -0,0 +1,183 @@ +--- +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 update \ + --access-token YOUR_ACCESS_TOKEN \ + --project PROJECT_KEY \ + --flag my-first-flag \ + --data '{"environmentKey": "ENVIRONMENT_KEY", "instructions": [{"kind": "turnFlagOn"}]}' +``` + +## 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 + +**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/sdk-recipes.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md new file mode 100644 index 0000000..e6b2577 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md @@ -0,0 +1,401 @@ +--- +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. + +## 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). +``` + +--- + +## 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); +``` + +### 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(); +``` From 66e9b4ef01f099dd0a6ce59d527d91c830d55ceb Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:09:38 +0000 Subject: [PATCH 2/5] address PR review feedback: fix prerequisites, SDK coverage, validation, and toggle commands - SKILL.md: Replace static prerequisites with dynamic account setup flow, add Step 7 (MCP Server Installation), renumber Recover to Step 8, fix 'No package manager' edge case to ask user which SDK they want - 1.0-detect.md: Add C/C++, Haskell, Lua, Roku, .NET client, edge SDK detection; add React Native, JS browser, Flutter, Swift, Android entrypoints; add SDK confirmation flow; ask user if language undetectable - 1.1-plan.md: Add edge SDKs, .NET client, C/C++, Haskell, Lua, Roku to SDK selection table; add Node.js client SDK note; reference detect step results for files to modify - 1.3-run.md: Remove reliance on log messages for success; use sdk-active endpoint for definitive validation; reframe indicators as startup errors - 1.4-validate.md: Fix API endpoint path to correct format; promote ldcli sdk-active as preferred option; add retry logic with 3-attempt limit; simplify dashboard option to flags page URL - 1.5-first-flag.md: Use ldcli flags toggle-on instead of flags update; add auth error handling section (prompt login/signup on 401/403) - marketplace.json: Move MCP server from requirements to optional - sdk-recipes.md: Add canonical ldcli sdk_instructions reference; add Haskell, Lua, C++ server, .NET client, C++ client, Roku recipes; add Edge SDKs section (Cloudflare, Vercel, Akamai) - New: 1.7-mcp-setup.md for MCP server installation guidance Co-Authored-By: Ari Salem --- .../launchdarkly-sdk-onboarding/SKILL.md | 33 +++-- .../marketplace.json | 3 +- .../references/1.0-detect.md | 34 ++++- .../references/1.1-plan.md | 25 +++- .../references/1.3-run.md | 43 +++++-- .../references/1.4-validate.md | 56 +++++---- .../references/1.5-first-flag.md | 17 ++- .../references/1.7-mcp-setup.md | 119 ++++++++++++++++++ .../references/sdk-recipes.md | 99 +++++++++++++++ 9 files changed, 373 insertions(+), 56 deletions(-) create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.7-mcp-setup.md diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md index 825aad6..ce4d9a3 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md @@ -12,11 +12,17 @@ metadata: 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. -## Prerequisites +## Account and Credentials -- A LaunchDarkly account with an API access token (or SDK key) -- A project and environment configured in LaunchDarkly -- Access to the user's codebase (read and write) +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 @@ -27,7 +33,7 @@ You're using a skill that will guide you through adding LaunchDarkly to a projec ## Workflow -Follow these steps in order. If any step fails, go to [Step 7: Recover](#step-7-recover). +Follow these steps in order. If any step fails, go to [Step 8: Recover](#step-8-recover). ### Step 1: Detect Repository Stack @@ -88,7 +94,19 @@ Help the user create and evaluate a feature flag. See [Create First Feature Flag](references/1.5-first-flag.md) for detailed instructions. -### Step 7: Recover +### 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: Recover If any step fails, diagnose the issue and resume. @@ -105,7 +123,7 @@ See [Recovery Procedures](references/1.6-recover.md) for detailed instructions. | 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 | Provide manual install instructions from the SDK recipe | +| 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 @@ -125,4 +143,5 @@ See [Recovery Procedures](references/1.6-recover.md) for detailed instructions. - [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 - [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 index 36996a1..454e5ca 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json +++ b/skills/onboarding/launchdarkly-sdk-onboarding/marketplace.json @@ -14,7 +14,8 @@ "setup", "mcp" ], - "requirements": { + "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 index 95b0565..644f843 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.0-detect.md @@ -15,21 +15,29 @@ Look for these files to identify the stack: | File | Language/Framework | |------|--------------------| -| `package.json` | JavaScript/TypeScript (check for React, Next.js, Vue, Angular, Express, etc.) | +| `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) | +| `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/Kotlin (check for Spring, Quarkus, Android) | | `Gemfile` | Ruby (check for Rails, Sinatra) | -| `*.csproj`, `*.sln` | .NET/C# | +| `*.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 | +| `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: @@ -51,12 +59,17 @@ Use the detected package manager for all install commands. If multiple lock file Find the main file where the application starts. Common patterns: -- **Node.js**: Check `package.json` `"main"` field, or look for `index.js`, `server.js`, `app.js`, `src/index.ts` +- **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 @@ -72,14 +85,23 @@ Check: - 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: +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 diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md index 3e8d7b1..66ddb32 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.1-plan.md @@ -17,12 +17,25 @@ Use the [SDK Recipes](sdk-recipes.md) reference to match the detected stack to a | 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 | Client-side ID | +| 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. If it's Electron, use the client-side SDK. +- **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 @@ -30,9 +43,11 @@ Your integration plan should identify exactly: ### 1. Files to Modify -- **Dependency file**: `package.json`, `requirements.txt`, `go.mod`, etc. (for the SDK dependency) -- **Entrypoint file**: Where SDK initialization code will go -- **Environment/config file**: `.env`, `.env.example`, or equivalent (for the SDK key) +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 diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md index 2103328..96f9f22 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.3-run.md @@ -26,18 +26,20 @@ If the project has a README with run instructions, follow those. ## Step 2: Start the Application -Run the application and watch the output for: +Run the application. Do NOT rely on specific log messages to determine success — different SDKs log differently and some don't log at all. -### Success Indicators -- `LaunchDarkly SDK initialized successfully` or similar log message +### What to Look For +- The application starts without crashing - No import errors or module-not-found errors -- The application starts and is ready to serve (e.g., "listening on port 3000") +- The app is responsive (e.g., serves HTTP requests, renders UI) -### Failure Indicators -- `SDK failed to initialize` — likely an invalid SDK key -- `Module not found` or `ImportError` — the SDK wasn't installed correctly -- `TypeError` or `undefined` — initialization code may have a syntax issue -- Network timeout — the SDK can't reach LaunchDarkly (check firewall/proxy) +### 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 @@ -51,11 +53,26 @@ Run the application and watch the output for: ## Step 4: Confirm SDK Activity -If the application starts successfully, look for signs the SDK is connected: +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" +``` -- SDK initialization log message in the console -- No error messages related to LaunchDarkly -- The application is running and responsive +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. diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md index 91b35de..7fcab25 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.4-validate.md @@ -7,21 +7,26 @@ description: Confirm that LaunchDarkly sees the SDK connection using the API or 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 MCP (Preferred) +## Option A: Validate via ldcli (Preferred) -If the LaunchDarkly MCP server is available, use the `get-environment` tool to check the SDK status: +The `ldcli sdk-active` command is the fastest way to check if the SDK is connected: -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 +```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 the MCP server is not available, use the LaunchDarkly REST API: +If `ldcli` is not available, use the REST API directly: ```bash curl -s -X GET \ - "https://app.launchdarkly.com/api/v2/sdk-active/PROJECT_KEY/ENVIRONMENT_KEY" \ + "https://app.launchdarkly.com/api/v2/projects/PROJECT_KEY/environments/ENVIRONMENT_KEY/sdk-active" \ -H "Authorization: LAUNCHDARKLY_ACCESS_TOKEN" ``` @@ -32,25 +37,21 @@ Replace: A successful response means the SDK has connected to LaunchDarkly. -## Option C: Validate via ldcli +## Option C: Validate via MCP -If the `ldcli` CLI is installed: +If the LaunchDarkly MCP server is available, use the `get-environment` tool to check the SDK status: -```bash -ldcli sdk-active \ - --access-token YOUR_ACCESS_TOKEN \ - --project PROJECT_KEY \ - --environment ENVIRONMENT_KEY -``` +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 -Direct the user to check the LaunchDarkly dashboard: +As a fallback, direct the user to check: + +**https://app.launchdarkly.com/projects/default/flags** -1. Go to **https://app.launchdarkly.com** -2. Navigate to the project and environment -3. Check **Settings > Environments** — look for a green "SDK connected" indicator -4. Or create a flag and check if the SDK version appears in the flag's evaluation insights +If the SDK is connected, the flags page will show evaluation data and SDK version information. ## Interpreting Results @@ -62,14 +63,27 @@ Direct the user to check the LaunchDarkly dashboard: | 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 multiple attempts: +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). 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 index 9d9cec0..73e2aa4 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.5-first-flag.md @@ -141,11 +141,11 @@ curl -s -X PATCH \ ### Via ldcli ```bash -ldcli flags update \ +ldcli flags toggle-on \ --access-token YOUR_ACCESS_TOKEN \ --project PROJECT_KEY \ - --flag my-first-flag \ - --data '{"environmentKey": "ENVIRONMENT_KEY", "instructions": [{"kind": "turnFlagOn"}]}' + --environment ENVIRONMENT_KEY \ + --flag my-first-flag ``` ## Step 5: Verify the Toggle @@ -167,6 +167,17 @@ The user has successfully: 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 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/sdk-recipes.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md index e6b2577..8ef3ddb 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/sdk-recipes.md @@ -7,6 +7,10 @@ description: Detection patterns, install commands, import statements, and initia 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. @@ -208,6 +212,39 @@ 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 @@ -281,6 +318,51 @@ await client.waitForInitialization(); 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 | @@ -399,3 +481,20 @@ import { LDProvider, useFlags } from '@launchdarkly/react-native-client-sdk'; // 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) | From 147f673335ab0cbd79572e47f0d193200228090a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:13:01 +0000 Subject: [PATCH 3/5] add onboarding summary and editor rules steps - New Step 8: Leave behind LAUNCHDARKLY.md with setup details, dashboard links, next steps (rollouts, experiments, AI configs, observability), and useful ldcli commands - New Step 9: Detect user's editor and create rules file (.cursorrules, .claude/rules, .github/copilot-instructions.md) with LaunchDarkly flag management best practices and skills - Renumber Recover to Step 10 - Add references for 1.8-summary.md and 1.9-editor-rules.md Co-Authored-By: Ari Salem --- .../launchdarkly-sdk-onboarding/SKILL.md | 31 +++- .../references/1.8-summary.md | 117 ++++++++++++++ .../references/1.9-editor-rules.md | 151 ++++++++++++++++++ 3 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md create mode 100644 skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md index ce4d9a3..9e2f5a8 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/SKILL.md @@ -33,7 +33,7 @@ Before starting the SDK integration, ensure the user has access to LaunchDarkly: ## Workflow -Follow these steps in order. If any step fails, go to [Step 8: Recover](#step-8-recover). +Follow these steps in order. If any step fails, go to [Step 10: Recover](#step-10-recover). ### Step 1: Detect Repository Stack @@ -106,7 +106,32 @@ The MCP server enables richer agent-driven workflows like flag management, targe See [MCP Server Setup](references/1.7-mcp-setup.md) for detailed instructions. -### Step 8: Recover +### 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. @@ -144,4 +169,6 @@ See [Recovery Procedures](references/1.6-recover.md) for detailed instructions. - [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/references/1.8-summary.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md new file mode 100644 index 0000000..cfd694f --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md @@ -0,0 +1,117 @@ +--- +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. + +### 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..6b77624 --- /dev/null +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md @@ -0,0 +1,151 @@ +--- +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, ask the user which editor they're using. + +## 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 + +### 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 +``` From ee937698dfc6a4ada95fcd6d0ebd79116a965e10 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:21:26 +0000 Subject: [PATCH 4/5] add MCP server section to onboarding summary template Adds 'AI Agent Integration (MCP Server)' section to the LAUNCHDARKLY.md template encouraging users to install the MCP server, with examples of what agents can do: create/toggle flags, set up targeting, clean up stale flags, run experiments, manage AI configs. Includes install snippet. Co-Authored-By: Ari Salem --- .../references/1.8-summary.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md index cfd694f..ca4e9c0 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.8-summary.md @@ -72,6 +72,35 @@ Here are some things you can do now that LaunchDarkly is set up: - **[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: From c719ee753d156e26a8d6efd245d1995c9ffd2ede Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:23:13 +0000 Subject: [PATCH 5/5] editor rules: default to Claude, add feature-flag skill references - Default to Claude Code rules if editor can't be detected (instead of asking) - Add 'Agent Skills for Feature Flags' section referencing the four existing skills: flag-create, flag-targeting, flag-cleanup, flag-discovery Co-Authored-By: Ari Salem --- .../references/1.9-editor-rules.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 index 6b77624..95f812a 100644 --- a/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md +++ b/skills/onboarding/launchdarkly-sdk-onboarding/references/1.9-editor-rules.md @@ -19,7 +19,7 @@ Check for editor configuration files in the project root: | `.vscode/` (without Cursor indicators) | VS Code | | `.idea/` | JetBrains IDE | -If you can't detect the editor, ask the user which editor they're using. +If you can't detect the editor, default to Claude Code and create `.claude/rules/launchdarkly.md`. ## Step 2: Create the Rules File @@ -69,6 +69,13 @@ This project uses LaunchDarkly for feature flag management. - 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