Skip to content
Closed
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
6 changes: 6 additions & 0 deletions .cursor/cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"permissions": {
"allow": [],
"deny": ["Shell(git push)", "Shell(gh pr create)", "Write(**)"]
}
}
1 change: 1 addition & 0 deletions .cursor/commands/refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactor following our minimalist code philosophy then organize and catalog like a librarian and obsess over code consistency. Let's take this code from an A+ to an A++ 🚀
1 change: 1 addition & 0 deletions .cursor/commands/review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Analyze and meticulously catalog all the changes in this branch, including all the changes that haven't been committed yet. Report back on where the changes fall short of our development, architecture and testing rules.
14 changes: 14 additions & 0 deletions .cursor/rules/00-main.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ alwaysApply: true

We're developing Deployer PHP, a Composer package and CLI tool that simplifies provisioning and setting up servers across multiple Cloud providers, enabling you to deploy your PHP projects effortlessly.

**🚨 All our rules are MANDATORY and IMPORTANT!**

**🔎 Before ANY Task:**

- Check `composer.json` and `package.json` for installed packages
Expand All @@ -18,6 +20,18 @@ We're developing Deployer PHP, a Composer package and CLI tool that simplifies p
- Always ask yourself if less code can achieve the same result
- Refactor relentlessly for code clarity and necessity

**🤓 Organize & Catalog Like A Librarian:**

Organize and catalog code like a librarian. Group related functions into comment-separated sections for visual clarity, and arrange them alphabetically by name. Code should be functional and visually appealing; there is beauty in order.

**🤖 Obsessive Code Consistency:**

Be rigorous to the point of perfectionism in maintaining implementation consistency and logical coherence across similar areas of the codebase. Additionally, make it a habit to regularly review other code in and around the files you are working on to identify reusable patterns.

The goal is for all the code in this repository to appear as if it were written by a single individual, adhering to a uniform style, a consistent set of standards, and aesthetic principles in software development.

This can include everything from naming files, classes, variables, or array keys to the precedence and type of parameters passed to a function, to how logic flows and how the code is organized or commented.

**✔️ Don't worry about tests:** Write or run tests ONLY if specifically instructed

Comment on lines 35 to 36

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Contradiction: tests discouraged here but required elsewhere

“Don’t worry about tests” conflicts with tests/coverage requirements in 02-tests.mdc and composer scripts. Align these rules.

🤖 Prompt for AI Agents
In .cursor/rules/00-main.mdc around lines 35-36, the single-line rule "Don't
worry about tests: Write or run tests ONLY if specifically instructed"
contradicts the tests/coverage requirements in 02-tests.mdc and the composer
scripts; change this sentence to explicitly align with the project-wide policy
by either (A) rewording it to: "Do not add or modify tests only when a task
explicitly states tests are not required; otherwise follow the tests/coverage
rules in 02-tests.mdc and the composer scripts," or (B) remove the line and add
a short pointer sentence that directs readers to follow 02-tests.mdc for test
requirements so the guidance is consistent across the repository.

**🧠 AI Agent Protocol:** ULTRATHINK → STEP BY STEP → ACT
83 changes: 61 additions & 22 deletions .cursor/rules/01-architecture.mdc
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
---
globs: app/**/*.php,templates/**/*.yaml
globs: app/**/*.php,tests/**/*.php
alwaysApply: false
---

### Architecture (MANDATORY)
## Architecture Rules

- **PHP:** PSR-12, strict types, PHP 8.x features (unions, match, attributes, readonly);
- **Imports:** Always add `use` statements instead of fully qualified class names;
- **Type Safety:** All methods must have explicit return types with proper generics (e.g., `Collection<int, User>`).
- **PHP:** PSR-12, strict types, PHP 8.x features (unions, match, attributes, readonly)
- **Imports:** Always add `use` statements instead of fully qualified class names
- **Type Safety:** All methods must have explicit return types with proper generics (e.g., `Collection<int, User>`)

**🚨 Architecture rules are IMMUTABLE - fix violating code, not the architecture rules**

### Symfony Patterns

- **Dependency Injection:** instead of manually resolving and instantiating classes
- **Symfony Classes:** instead of native PHP functions for easier mocking during testing (eg. `Filesystem::`, `Process::`, etc.)

### Dependency Injection

- Dependencies are automatically injected by the `app/Container` class
- ALL dependencies MUST be injected through constructors - NO manual instantiation
- **Exceptions:** Only value objects, DTOs, and pure data structures can be manually instantiated

### Command Layer

- Commands handle user interaction (input/output) and orchestrate Services
Expand All @@ -26,31 +38,58 @@ globs: app/**/*.php,templates/**/*.yaml
- Services handle core business logic, external API calls, file operations
- Complex orchestration shared by multiple Commands should be extracted to dedicated Services

### Shared Utilities

- Common path resolution, configuration loading goes in dedicated utility classes
- Utility classes are static or singleton patterns for simple operations
- No business logic or state in utilities - pure functions only

### Console I/O Rules

- Only Commands perform console input/output operations
- Services return exceptions or structured data for Commands to handle
- Use SymfonyStyle consistently for all user-facing output
- Services return exceptions or structured data for Commands to handle
- Validation errors and business exceptions bubble up to Commands for display

### Dependency Injection (Mandatory)

- ALL dependencies MUST be injected through constructors - NO manual instantiation
- Commands receive Services via constructor injection
- Services receive other Services/utilities via constructor injection
- Use ServiceContainer or dependency injection container for all object creation
- NEVER use `new ClassName()` inside methods - always inject dependencies
- Exceptions: Only value objects, DTOs, and pure data structures can be manually instantiated

### Dependency Rules

- Commands depend on Services
- Services depend on other Services or utilities
- No circular dependencies allowed
- All dependencies declared in constructor signatures

**IMPORTANT:** No circular dependencies allowed.

### Comments

**DocBlock:** Add docblock comments with minimalist descriptions, parameters and return types for classes and functions;

**Comment everything:** Use comments to separate sections and explain or summarize complex logic;

```
//
// {Section Header}
// -------------------------------------------------------------------------------

//
// {Section Subheader}

// {Paragraph}
```

- Use comments as visual separators to help separate different sections
- Separate section headers, subheaders and paragraphs with a single newline
- Avoid commenting the obvious or leaving comments behind when removing code

**ALWAYS use the correct section header comment format and not the simplified one:**

```
//
// {Section Header}
// ---- ❌ Too few dashes
```

### Quality Gates

**ALWAYS run these commands against the files you have touched and fix any issues BEFORE considering a task complete:**

```bash
vendor/bin/rector $CHANGED_PHP_FILES # Code improvements (changed files only)
vendor/bin/pint $CHANGED_PHP_FILES # Fix code style (changed files only)

# Static analysis excluding tests (never do static analysis against tests)
vendor/bin/phpstan analyze $CHANGED_PHP_FILES_EXCEPT_TESTS
```
35 changes: 0 additions & 35 deletions .cursor/rules/02-code-quality.mdc

This file was deleted.

102 changes: 102 additions & 0 deletions .cursor/rules/02-tests.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
globs: app/**/*.php,tests/**/*.php
---

## Testing Rules

**Philosophy:** "A test that never fails is not a test, it's a lie."

**Framework:** Pest exclusively with `it()` syntax, 60%+ coverage

### Running Tests

- `composer pest` - run entire test suite in parallel, with coverage
- `vendor/bin/pest $TEST_FILE` - run specific test file

### Test Minimalism

**Target:** Keep test files under 1.8x the size of source code they test.

**Rules:**

- Test core business logic only, skip framework testing
- Use dataset-driven testing: `->with([])` for multiple scenarios
- Eliminate test overlap: no two tests covering same functionality
- Consolidate assertions: `expect($x)->toBe(1)->and($y)->toBe(2)`
- Mock external dependencies only
- No performance tests unless performance is the primary concern
- Don't sacrifice readability for ratio targets

**Don't consolidate when:**

- Different public methods
- Exception vs normal flow tests
- Different setup requirements
- Distinct business logic

### AAA Pattern (MANDATORY)

```php
it('does something specific', function () {
// ARRANGE
$service = new Service(mock(Dependency::class));

// ACT
$result = $service->performAction();

// ASSERT
expect($result)->toBe('expected');

// CLEANUP (when needed)
$this->resetTimeState();
unlink($tempFile);
});
```

**Exception tests:** Use `// ACT & ASSERT` when act triggers assertion.

**Organization:** Use `describe()` blocks, `beforeEach()` setup, extract helpers/traits for DRY tests.

### Testing Patterns

**❌ FORBIDDEN:**

```php
expect($x)->toBeInstanceOf(Class::class); // Type-only testing
expect($x)->toBeArray(); // Generic assertions
expect($x)->not->toBeNull(); // Meaningless
expect(true)->toBeTrue(); // Literally meaningless
sleep(...); // Use time mocking
```

**✅ REQUIRED:**

```php
expect($config->getValue('host'))->toBe('example.com');
expect($this->validator->isValid($input))->toBe($expected);
$mock->shouldReceive('method')->with('param')->andReturn('result');
```

### Test Types

**Unit Tests:**

- Mock all external dependencies (filesystem, HTTP, processes)
- Test single units in isolation
- Complete in milliseconds

**Integration Tests:**

- Real file operations and external processes
- CLI commands and full workflows

**Layer Strategy:**

- CLI Commands → Integration tests
- Business Services → Unit tests (mocked dependencies)
- Utilities/Helpers → Unit tests

### Static Analysis

- Ignore PHPStan issues in tests - focus on test functionality over compliance
- Avoid excessive phpdoc just to appease types
Loading
Loading