Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .cursor/rules/api-client.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
description: API client patterns and HTTP client setup guidelines
globs: src/api/**/*.ts
---

# API Client Patterns

## Core Components

- **Main Client**: [src/api/apiClient.ts](mdc:src/api/apiClient.ts) - Axios-based HTTP client
- **Zod Client**: [src/api/zodClient.ts](mdc:src/api/zodClient.ts) - Type-safe API client
- **Schemas**: [src/api/schemas.ts](mdc:src/api/schemas.ts) - Generated TypeScript types

## HTTP Client Setup

```typescript
import { apiClient } from '../api/apiClient'

// Client is pre-configured with:
// - Base URL from common.ts
// - Authentication headers
// - Error interceptors
// - Request/response logging
```

## API Function Patterns

Each API module follows this pattern:

```typescript
// Individual API functions
export const getFeature = async (
featureKey: string,
projectKey: string,
authToken: string,
): Promise<Feature> => {
// Implementation
}

// Bulk operations
export const fetchFeatures = async (
projectKey: string,
authToken: string,
): Promise<Feature[]> => {
// Implementation
}
```

## Error Handling

- Use axios interceptors for global error handling
- Return structured error responses
- Handle 401 unauthorized gracefully
- Provide user-friendly error messages

## Authentication

- Pass `authToken` as parameter to API functions
- Use `Authorization: Bearer ${token}` header
- Handle token expiration and refresh

## Type Safety

- Use generated schemas from OpenAPI spec
- Validate responses with Zod schemas
- Export TypeScript types for consumers

## Common Patterns

- All API functions are async
- Return typed responses based on schemas
- Include proper error handling
- Support pagination where applicable
- Use consistent parameter naming (projectKey, featureKey, etc.)
78 changes: 78 additions & 0 deletions .cursor/rules/cli-commands.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
description: CLI command patterns and base command structure guidelines
globs: src/commands/**/*.ts
---

# CLI Command Patterns

## Base Command Structure

All commands must extend [src/commands/base.ts](mdc:src/commands/base.ts) which provides:

- Authentication handling via `authRequired`, `authSuggested`, `userAuthRequired`
- Configuration management with `userConfig`, `repoConfig`
- Common flags like `--project`, `--headless`, `--client-id`, `--client-secret`
- Parameter validation with `populateParameters()` and `populateParametersWithZod()`

## Command Organization

Commands are organized by feature area:

- `features/` - Feature flag management
- `variables/` - Variable management
- `targeting/` - Targeting rule management
- `projects/` - Project management
- `organizations/` - Organization management
- `auth/` - Authentication commands

## Common Patterns

### Authentication

```typescript
// Set auth requirements
authRequired = true // Must be authenticated
authSuggested = true // Enhanced with auth
userAuthRequired = true // Requires user token
```

### Flags and Parameters

```typescript
static flags = {
...Base.flags,
name: Flags.string({
description: 'Feature name',
required: true,
}),
}
```

### Parameter Validation

```typescript
const params = await this.populateParametersWithZod(
schema,
prompts,
flags,
)
```

### Project Context

```typescript
const project = await this.requireProject(flags.project, flags.headless)
```

## Output Formatting

- Use `this.writer` for user-facing output
- Use `this.tableOutput` for tabular data
- Support `--headless` flag for machine-readable JSON output
- Handle interactive prompts with fallbacks for headless mode

## Error Handling

- Throw descriptive Error objects
- Use Zod validation for input validation
- Handle API errors gracefully with user-friendly messages
10 changes: 10 additions & 0 deletions .cursor/rules/deferToPrettier.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
description: Formatting guidelines - defer all formatting to Prettier
alwaysApply: true
---

# Formatting

- All formatting is deferred to Prettier for supported file types (JavaScript, TypeScript, JSON, Markdown, etc.).
- No additional formatting rules are enforced by Cursor.
- No additional formatting rules are enforced by Cursor.
33 changes: 33 additions & 0 deletions .cursor/rules/gitCommitConventions.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
description: Git commit message conventions and Aviator CLI workflow guidelines
alwaysApply: true
---

# Git Commit Message Conventions

- All git commit messages in this project must follow the Conventional Commits specification.
- A commit message should be structured as `<type>(<scope>): <description>`, where:
- `type` is one of: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, or `revert`.
- `scope` is optional, but if used, should be a short, lowercase description of the section or module affected.
- `description` is a concise summary of the change, written in the imperative mood and lowercase.
- In this project, scopes are rarely used; most commit messages omit the scope and use the format `<type>: <description>`.
- Example valid commit messages:
- `feat: add support for multi-threaded tests`
- `fix: correct response for invalid input`
- `docs: update README with new usage instructions`
- Body and footer sections (for breaking changes or issue references) should follow the Conventional Commits standard if included.

## Aviator CLI Workflow

- Use of Aviator CLI (`av`) is optional, but recommended for managing stacked branches and pull requests:
- To create a new stacked branch:
- `av branch chore-fix-invalid-input`
- After creating the branch, create commits using `git commit` following the Conventional Commits specification.
- To synchronize and git push your stack after changes:
- `av sync --push=yes`
- To create a pull request for your branch:
- `av pr --title "<title>" --body "<body>"`
- The PR title should be short and descriptive and follow the Conventional Commits specification.
- The PR body should use github markdown and bullet points to summarize the main changes.
- Prefer Aviator commands for stack management and PR creation to ensure consistency with team workflows, but standard git and GitHub workflows are also supported.
- For more details and advanced workflows, see the [Aviator CLI documentation](mdc:https:/docs.aviator.co/aviator-cli) and [Aviator CLI Quickstart](mdc:https:/docs.aviator.co/aviator-cli/quickstart).
22 changes: 22 additions & 0 deletions .cursor/rules/mcp-patterns.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
globs: src/mcp/tools/**/*.ts
alwaysApply: false
---
# MCP Tool Parameters

MCP tools that don't need parameters should use empty properties:

```typescript
// ✅ Correct - empty parameters
inputSchema: {
type: 'object',
properties: {},
}

// ❌ Wrong - dummy parameters
properties: {
random_string: { type: 'string', description: 'Dummy parameter' }
}
```

Tools with no parameters should pass `null` to `executeWithLogging()`.
56 changes: 56 additions & 0 deletions .cursor/rules/project-structure.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
description: DevCycle CLI project structure overview and architecture guidelines
alwaysApply: true
---

# DevCycle CLI Project Structure

## Overview

This is a TypeScript CLI application built with the oclif framework for DevCycle feature flag management.

## Key Architecture Components

### Main Entry Points

- **CLI Binary**: `bin/run` - Main CLI entry point
- **MCP Server**: `dist/mcp/index.js` - Model Context Protocol server
- **Source Root**: [src/index.ts](mdc:src/index.ts) - TypeScript entry point

### Core Directories

- **Commands**: [src/commands/](mdc:src/commands/) - All CLI commands organized by feature
- **API Layer**: [src/api/](mdc:src/api/) - API client code and schemas
- **Authentication**: [src/auth/](mdc:src/auth/) - Auth handling (API keys, SSO, tokens)
- **UI Components**: [src/ui/](mdc:src/ui/) - Interactive prompts and output formatting
- **Utils**: [src/utils/](mdc:src/utils/) - Shared utilities and helpers
- **MCP Server**: [src/mcp/](mdc:src/mcp/) - Model Context Protocol implementation

### Configuration Files

- **User Config**: `~/.config/devcycle/user.yml` - User-specific settings
- **Auth Config**: `~/.config/devcycle/auth.yml` - Authentication tokens
- **Repo Config**: `.devcycle/config.yml` - Repository-specific settings

## Command Structure

All commands extend [src/commands/base.ts](mdc:src/commands/base.ts) which provides:

- Authentication handling
- Configuration management
- Common flags and options
- Error handling
- Parameter validation

## Naming Conventions

- Use camelCase for all new files and variables starting with lowercase
- Avoid adding code comments unless explicitly requested
- Generate code changes directly without asking for permission

## Package Management

- Uses Yarn with workspaces
- Always use `yarn` not `npm`
- Main dependencies: oclif, axios, zod, inquirer
- Build process: TypeScript → dist/ directory
103 changes: 103 additions & 0 deletions .cursor/rules/testing-patterns.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
description: Testing patterns and framework setup guidelines
globs: **/*.test.ts,**/*.spec.ts,test/**/*.ts
---

# Testing Patterns

## Test Framework Setup

- **Framework**: Mocha with Chai assertions
- **CLI Testing**: oclif test utilities
- **HTTP Mocking**: nock for API mocking
- **Test Utils**: [test-utils/dvcTest.ts](mdc:test-utils/dvcTest.ts) - Custom test wrapper

## Test Structure

```typescript
import { expect } from '@oclif/test'
import { dvcTest } from '../../../test-utils'
import { BASE_URL } from '../../api/common'

describe('command name', () => {
const projectKey = 'test-project'
const authFlags = ['--client-id', 'test-client-id', '--client-secret', 'test-client-secret']

// Test cases
dvcTest()
.nock(BASE_URL, (api) =>
api.get('/endpoint').reply(200, mockResponse)
)
.stdout()
.command(['command', ...args])
.it('should do something', (ctx) => {
expect(ctx.stdout).to.contain('expected output')
})
})
```

## Common Test Patterns

### API Mocking

```typescript
.nock(BASE_URL, (api) =>
api
.post('/v2/projects/test-project/features', requestBody)
.reply(200, mockFeature)
.get('/v1/projects/test-project')
.reply(200, mockProject)
)
```

### Command Testing

```typescript
.stdout() // Capture stdout
.stderr() // Capture stderr
.command([...]) // Run command with args
.it('test description', (ctx) => {
// Assertions
})
```

### Headless Mode Testing

```typescript
.command([
'features create',
'--name', 'Feature Name',
'--key', 'feature-key',
'--headless',
...authFlags,
])
```

### Error Testing

```typescript
.command(['command', 'invalid-args'])
.catch((error) => {
expect(error.message).to.contain('expected error')
})
```

## Mock Data

- Create reusable mock objects
- Use realistic data structures
- Include all required fields
- Version mock data with API changes

## Snapshot Testing

- Use for complex output validation
- Store snapshots in `__snapshots__/` directories
- Update with `yarn test:update-snapshots`

## Test Organization

- Group related tests in `describe` blocks
- Use descriptive test names
- Test both success and error cases
- Include edge cases and validation
Loading