Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
49bf32b
Update AI rules with clarifications and pattern fixes
tjementum Nov 30, 2025
38456e4
Improve commit workflow with auto-sync and clearer structure
tjementum Nov 30, 2025
1369990
Improve workflow structure and add mandatory preparation steps
tjementum Nov 30, 2025
89a29a2
Add agentic workflow for autonomous feature implementation via task d…
tjementum Nov 30, 2025
84d3af5
Add mode commands for tech-lead, coordinator, and agentic workflow do…
tjementum Nov 30, 2025
68bbfcd
Add Claude Code agent definitions for engineers, reviewers, and paral…
tjementum Nov 30, 2025
411f744
Add system prompts for Claude Code agentic workflow worker-host sessions
tjementum Nov 30, 2025
4ecea1a
Add Chrome DevTools MCP config for frontend and end-to-end agent brow…
tjementum Nov 30, 2025
12d6ea0
Add Claude Code hooks and settings for safe git operations
tjementum Nov 30, 2025
e572203
Add git helpers to detect recent commits and file modifications
tjementum Nov 30, 2025
39221c2
Add file-based logger for agentic workflow tracking
tjementum Nov 30, 2025
c5c37ef
Add CLI command for spawning and managing Claude Code agents
tjementum Nov 30, 2025
f9b7bae
Add agent lifecycle helpers for completing tasks and reviews
tjementum Nov 30, 2025
725dbaa
Add init-task-manager cli command for workspace setup
tjementum Nov 30, 2025
b72c560
Add MCP tools for worker agent lifecycle and problem reporting
tjementum Nov 30, 2025
b73dbd0
Update README with Claude Code autonomous development workflow
tjementum Nov 30, 2025
06b09c2
Soften language in AI rules and commands with Opus 4.5 best practices
tjementum Dec 1, 2025
cdc5369
Update backend testing and domain modeling rules
tjementum Dec 1, 2025
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
2 changes: 1 addition & 1 deletion .agent/rules/backend/api-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for ASP.NET minimal API endpoints
---
# API Endpoints

Carefully follow these instructions when implementing minimal API endpoints in the backend, including structure, route conventions, and usage patterns.
Guidelines for implementing minimal API endpoints in the backend, including structure, route conventions, and usage patterns.

## Implementation

Expand Down
38 changes: 27 additions & 11 deletions .agent/rules/backend/api-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for writing backend API tests
---
# Writing API Tests

Carefully follow these instructions when writing tests for the backend. By default, tests should test API endpoints to verify behavior over implementation. Only in rare cases should unit tests be used.
Guidelines for writing tests for the backend. By default, tests should test API endpoints to verify behavior over implementation. Only in rare cases should unit tests be used.

## Implementation

Expand All @@ -29,7 +29,7 @@ Carefully follow these instructions when writing tests for the backend. By defau
10. Test both happy path and error cases
11. Avoid sharing fields between tests—prefer local constants or variables within each test method
12. Verify side effects like database changes and telemetry events
13. Always call `TelemetryEventsCollectorSpy.Reset()` as the last Arrange statement if API calls were used to set up state
13. Always call `TelemetryEventsCollectorSpy.Reset()` as the last Arrange statement if API calls were used to set up state (to ensure only the events from the Act phase are verified)
14. Use the `Connection` property from `EndpointBaseTest<TContext>` for test data—it provides a SQLite connection with:
- `Insert` to populate test data
- `Update` to update test data
Expand All @@ -44,7 +44,7 @@ Carefully follow these instructions when writing tests for the backend. By defau
- Telemetry event collection
- Proper test cleanup with the Dispose pattern

IMPORTANT: Ensure consistent ordering, naming, spacing, and line breaks. When creating SQL dummy data, ensure columns are in the exact same order as in the database. Make sure similar elements are written consistently across tests.
Ensure consistent ordering, naming, spacing, and line breaks. When creating SQL dummy data, ensure columns are in the exact same order as in the database. Make sure similar elements are written consistently across tests.

## Examples

Expand Down Expand Up @@ -78,29 +78,45 @@ public async Task BadTest()
// ❌ DON'T: Skip verifying DB or telemetry side effects
}

// ✅ DO: Use SQLite helpers for test data setup, consistent column order
public GetUsersTests()
// ✅ DO: Create helper methods for test data, call them in // Arrange
private string InsertTestUser(string? email = null)
{
var userId = UserId.NewId().ToString();
Connection.Insert("Users", [
("TenantId", DatabaseSeeder.Tenant1.Id.ToString()),
("Id", UserId.NewId().ToString()),
("Id", userId),
("CreatedAt", TimeProvider.System.GetUtcNow().AddMinutes(-10)), // ✅ DO: Use TimeProvider for dates
("ModifiedAt", null),
("Email", Email)
("Email", email ?? Faker.Internet.Email())
]);
return userId;
}

// ❌ DON'T: Use Dapper in tests
[Fact]
public async Task GetUser_WhenUserExists_ShouldReturnUser()
{
// Arrange
var userId = InsertTestUser("test@example.com"); // ✅ DO: Call helper in Arrange - makes test self-contained

// Act
var response = await AuthenticatedOwnerHttpClient.GetAsync($"/api/users/{userId}");

// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
}

// ❌ DON'T: Create test data in constructors or use Dapper
public class BadTestSetup
{
public BadTestSetup() // ❌ DON'T: Add setup logic to constructor
public BadTestSetup()
{
// Arrange
// ❌ DON'T: Add setup logic to constructor - tests become implicit and harder to understand
using var connection = new SqliteConnection(Connection.ConnectionString); // ❌ DON'T: Use Dapper
connection.Open();

// Insert user // ❌ DON'T: Add comments
connection.Execute("INSERT INTO Users (Email, Id, TenantId) VALUES (@Email, @Id, @TenantId)", new { Email = "test@example.com", Id = Guid.NewGuid(), TenantId = 1 });
connection.Execute("INSERT INTO Users ...");
connection.Execute("INSERT INTO Users (Email, Id, TenantId) VALUES (@Email, @Id, @TenantId)", new { Email = "test@example.com", Id = Guid.NewGuid(), TenantId = 1 }); // ❌ DON'T: Use Dapper Execute
}
}
```
4 changes: 2 additions & 2 deletions .agent/rules/backend/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Core rules for C# development and tooling
---
# Backend

Carefully follow these instructions for C# backend development, including code style, naming, exceptions, logging, and build/test/format workflow.
Guidelines for C# backend development, including code style, naming, exceptions, logging, and build/test/format workflow.

## Code Style

Expand Down Expand Up @@ -104,7 +104,7 @@ Carefully follow these instructions for C# backend development, including code s

## Implementation

IMPORTANT: Always follow these steps very carefully when implementing changes:
Follow these steps when implementing changes:

1. Always start new changes by writing new test cases (or change existing tests)—consult [API Tests](/.agent/rules/backend/api-tests.md) for details
2. Build and test your changes:
Expand Down
2 changes: 1 addition & 1 deletion .agent/rules/backend/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for implementing CQRS commands, validation, handlers, and str
---
# CQRS Commands

Carefully follow these instructions when implementing CQRS commands, including structure, validation, handlers, and MediatR pipeline behaviors.
Guidelines for implementing CQRS commands, including structure, validation, handlers, and MediatR pipeline behaviors.

## Structure

Expand Down
6 changes: 3 additions & 3 deletions .agent/rules/backend/database-migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ description: Rules for creating database migrations
---
# Database Migrations

Carefully follow these instructions when creating database migrations.
Guidelines for creating database migrations.

## Implementation

1. Create migrations manually rather than using Entity Framework tooling:
- Place migrations in `/[scs-name]/Core/Database/Migrations`
- Name migration files with 14-digit timestamp prefix: `YYYYMMDDHHmmss_MigrationName.cs`
- Only implement the `Up` method—do NOT create `Down` migration
- Only implement the `Up` method—don't create `Down` migration

2. Follow this strict column ordering in table creation statements:
- `TenantId` (if applicable)
Expand All @@ -22,7 +22,7 @@ Carefully follow these instructions when creating database migrations.
- All other properties in the same order as they appear in the C# Aggregate class

3. Use appropriate SQL Server data types:
- For strongly typed IDs, default to `varchar(32)` (ULID is 26 chars + underscore + max 5-char prefix)
- Use `varchar(32)` for strongly typed IDs (ULID is 26 chars + underscore + max 5-char prefix = exactly 32)
- Intelligently deduce varchar vs nvarchar based on property type, validators, enum values, etc.
- Use `datetimeoffset` (default), `datetime2` (timezone agnostic), or `date`—never `datetime`
- Default to `varchar(10)` or `varchar(20)` for enum values
Expand Down
15 changes: 13 additions & 2 deletions .agent/rules/backend/domain-modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for creating DDD aggregates, entities, value objects, and Ent
---
# Domain Modeling

Carefully follow these instructions when implementing DDD models for aggregates, entities, and value objects.
Guidelines for implementing DDD models for aggregates, entities, and value objects.

## Implementation

Expand Down Expand Up @@ -155,14 +155,25 @@ public class BadInvoice : AggregateRoot<BadInvoiceId>
public List<BadInvoiceLine> InvoiceLines { get; set; } = new();
}

public sealed class BadInvoiceConfiguration : IEntityTypeConfiguration<BadInvoice>
public sealed class BadInvoiceConfiguration : IEntityTypeConfiguration<BadInvoice>
{
public void Configure(EntityTypeBuilder<BadInvoice> builder)
{
builder.Property(t => t.Name).HasMaxLength(100).IsRequired(); // ❌ DON'T: Configure primitive properties
builder.Property(t => t.Description).HasMaxLength(255); // ❌ DON'T: Configure primitive properties
builder.HasIndex(u => new { u.Email }).IsUnique(); // ❌ IsUnique is a database constraint, not needed by EF Core at runtime
builder.Property(u => u.Role).HasColumnType("varchar(10)").HasConversion<string>(); // ❌ EF is configured to convert all enums to string

// ❌ DON'T: Configure FK relationships without OnDelete - we don't use EF Tools for migrations
builder.HasOne<Tenant>()
.WithMany()
.HasForeignKey(i => i.TenantId);

// ✅ DO: Configure FK relationships only when you need cascade delete behavior at runtime
builder.HasOne<Customer>()
.WithMany()
.HasForeignKey(i => i.CustomerId)
.OnDelete(DeleteBehavior.Cascade); // EF needs this to handle cascades at runtime
}
}
```
2 changes: 1 addition & 1 deletion .agent/rules/backend/external-integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for creating external integration services
---
# External Integrations

Carefully follow these instructions when implementing integrations with external services in the backend, including structure, error handling, and client conventions.
Guidelines for implementing integrations with external services in the backend, including structure, error handling, and client conventions.

## Implementation

Expand Down
2 changes: 1 addition & 1 deletion .agent/rules/backend/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for CQRS queries, including structure, validation, response t
---
# CQRS Queries

Carefully follow these instructions when implementing CQRS queries, including structure, validation, response types, and MediatR pipeline behaviors.
Guidelines for implementing CQRS queries, including structure, validation, response types, and MediatR pipeline behaviors.

## Implementation

Expand Down
4 changes: 2 additions & 2 deletions .agent/rules/backend/repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for DDD repositories, including tenant scoping, interface con
---
# DDD Repositories

Carefully follow these instructions when implementing DDD repositories in the backend, including structure, interface conventions, and Entity Framework mapping.
Guidelines for implementing DDD repositories in the backend, including structure, interface conventions, and Entity Framework mapping.

## Implementation

Expand All @@ -16,7 +16,7 @@ Carefully follow these instructions when implementing DDD repositories in the ba
- Use `IBaseRepository` when you don't need all CRUD operations
- Only include methods needed for your specific aggregate
5. Only return Aggregates or custom projections—never Entities or Value Objects
6. Never return `[PublicAPI]` response DTOs
6. Never return `[PublicAPI]` response DTOs (repositories return domain objects; mapping to DTOs happens in query handlers)
7. Keep repositories focused on persistence operations, not business logic
8. Repositories are automatically registered in the DI container
9. Aggregates with `ITenantScopedEntity` are automatically filtered by tenant using EF Core query filters:
Expand Down
2 changes: 1 addition & 1 deletion .agent/rules/backend/strongly-typed-ids.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for creating strongly typed IDs for DDD aggregates and entiti
---
# Strongly Typed IDs

Carefully follow these instructions when implementing strongly typed IDs in the backend, covering type safety, naming, serialization, and EF Core mapping.
Guidelines for implementing strongly typed IDs in the backend, covering type safety, naming, serialization, and EF Core mapping.

## Implementation

Expand Down
2 changes: 1 addition & 1 deletion .agent/rules/backend/telemetry-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for telemetry events including important rules of where to cr
---
# Telemetry Events

Carefully follow these instructions when implementing telemetry events in the backend, including event structure, naming, and publishing practices.
Guidelines for implementing telemetry events in the backend, including event structure, naming, and publishing practices.

## Implementation

Expand Down
7 changes: 3 additions & 4 deletions .agent/rules/developer-cli/developer-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for implementing Developer CLI commands
---
# Developer Command Line Interface Rules

Carefully follow these instructions when implementing and extending the custom Developer Command Line Interface (CLI) commands.
Guidelines for implementing and extending the custom Developer Command Line Interface (CLI) commands.

## Implementation

Expand Down Expand Up @@ -112,9 +112,8 @@ public class BadBuildCommand : Command
{
public BadBuildCommand() : base("bad-build", "Bad build command")
{
// ❌ DON'T: Extract options to a variable
var option = new Option<string?>(["-file-name", "--f"], "The name of the solution to process") // ❌ Inconsistent option naming, wrong use of -- and -
AddOption(option);
// ❌ Use inconsistent option naming (single dash for long names, double dash for short)
AddOption(new Option<string?>(["-file-name", "--f"], "The name of the solution to process"));
Handler = CommandHandler.Create<string>(Execute);
}
private static int Execute(string file)
Expand Down
18 changes: 9 additions & 9 deletions .agent/rules/end-to-end-tests/end-to-end-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ These rules outline the structure, patterns, and best practices for writing end-
- Include JSDoc comments above complex tests listing all major features/scenarios covered
- When adding new functionality to existing tests, update both the test description and JSDoc comments to reflect changes

6. Structure each test with step decorators and proper monitoring:
6. Structure each test with step wrappers and proper monitoring:
- All tests must start with `const context = createTestContext(page);` for proper error monitoring
- Use step decorators: `await step("Complete signup & verify account creation")(async () => { /* test logic */ })();`
- Use step wrappers: `await step("Complete signup & verify account creation")(async () => { /* test logic */ })();`
- Step naming conventions:
- Always follow "[Business action + details] & [expected outcome]" pattern
- Use business action verbs like "Sign up", "Login", "Invite", "Rename", "Update", "Delete", "Create", "Submit"
Expand All @@ -76,14 +76,14 @@ These rules outline the structure, patterns, and best practices for writing end-
- Form validation pattern: Use `await blurActiveElement(page);` when updating a textbox the second time before submitting a form to trigger validation

7. Timeout Configuration:
- Always use Playwright's built-in auto-waiting assertions: `toHaveURL()`, `toBeVisible()`, `toBeEnabled()`, `toHaveValue()`, `toContainText()`
- Never add timeouts to `.click()`, `.waitForSelector()`, etc.
- Global timeout configuration is handled in the shared Playwright—do not change this
- Use Playwright's built-in auto-waiting assertions: `toHaveURL()`, `toBeVisible()`, `toBeEnabled()`, `toHaveValue()`, `toContainText()`
- Don't add timeouts to `.click()`, `.waitForSelector()`, etc.
- Global timeout configuration is handled in the shared Playwright—don't change this

8. Write deterministic tests—this is critical for reliable testing:
8. Write deterministic tests for reliable testing:
- Each test should have a clear, linear flow of actions and assertions
- Never use if statements, custom error handling, or try/catch blocks in tests
- Never use regular expressions in tests—use simple string matching instead
- Don't use if statements, custom error handling, or try/catch blocks in tests
- Don't use regular expressions in tests—use simple string matching instead

9. What to test:
- Enter invalid values such as empty strings, only whitespace characters, long strings, negative numbers, Unicode, etc.
Expand Down Expand Up @@ -157,7 +157,7 @@ await step("Ensure user is deleted")(async () => { // "Ensure" is assertion pref

### ✅ Complete Test Example
```typescript
import { step } from "@shared/e2e/utils/step-decorator";
import { step } from "@shared/e2e/utils/test-step-wrapper";
import { expectValidationError, blurActiveElement, createTestContext } from "@shared/e2e/utils/test-assertions";
import { testUser } from "@shared/e2e/utils/test-data";

Expand Down
31 changes: 15 additions & 16 deletions .agent/rules/frontend/form-with-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Rules for forms with validation using React Aria Components
---
# Form With Validation

Carefully follow these instructions when implementing forms with validation in the frontend, covering UI components, mutation handling, and validation error display.
Guidelines for implementing forms with validation in the frontend, covering UI components, mutation handling, and validation error display.

## Implementation

Expand All @@ -14,8 +14,13 @@ Carefully follow these instructions when implementing forms with validation in t
3. Use the custom `mutationSubmitter` to handle form submission and data mapping
4. Handle validation errors using the `validationErrors` prop from the mutation error
5. Show loading state in submit buttons
6. Include a `FormErrorMessage` component to display validation errors
7. For complex scenarios with multiple API calls, create a custom mutation with a `mutationFn`
6. For complex scenarios with multiple API calls, create a custom mutation with a `mutationFn`

## Anti-patterns

- **Do NOT use `<FormErrorMessage>`** - This component is deprecated. Instead:
- Use `validationErrors` prop on the `<Form>` to show field-level validation errors
- Use toast notifications to display server errors (non-validation errors)

Note: All .NET API endpoints are available as strongly typed API contracts in the frontend—when compiling the .NET backend, an OpenApi.json file is generated and the frontend build uses `openapi-typescript` to generate the API contracts.

Expand All @@ -27,7 +32,7 @@ Note: All .NET API endpoints are available as strongly typed API contracts in th
// ✅ DO: Use mutationSubmitter and proper error handling
import { api } from "@/shared/lib/api/client";
import { mutationSubmitter } from "@repo/ui/forms/mutationSubmitter";
import { Form, FormErrorMessage, TextField, Button } from "@repo/ui/components";
import { Form, TextField, Button } from "@repo/ui/components";
import { Trans } from "@lingui/react/macro";

export function UserProfileForm({ user }) {
Expand Down Expand Up @@ -55,15 +60,12 @@ export function UserProfileForm({ user }) {
placeholder={t`E.g., Taylor`}
/>

<TextField
name="title"
label={t`Title`}
defaultValue={user?.title}
<TextField
name="title"
label={t`Title`}
defaultValue={user?.title}
/>

{/* Error message display */}
<FormErrorMessage error={updateUserMutation.error} />


<Button type="submit" isDisabled={updateUserMutation.isPending}>
{updateUserMutation.isPending ? <Trans>Saving...</Trans> : <Trans>Save changes</Trans>}
</Button>
Expand Down Expand Up @@ -103,8 +105,6 @@ function BadUserProfileForm({ user }) {
<TextField name="lastName" defaultValue={user?.lastName} isRequired />
<TextField name="title" defaultValue={user?.title} />

{error && <FormErrorMessage error={error} />}

<Button type="submit" isDisabled={isLoading}>
{isLoading ? <Trans>Saving...</Trans> : <Trans>Save changes</Trans>}
</Button>
Expand Down Expand Up @@ -159,8 +159,7 @@ export function UserProfileWithAvatarForm({ user, onSuccess, onClose }) {
validationErrors={saveMutation.error?.errors || updateUserMutation.error?.errors}
>
{/* Form fields */}
<FormErrorMessage error={saveMutation.error} />


<Button type="submit" isDisabled={saveMutation.isPending}>
{saveMutation.isPending ? <Trans>Saving...</Trans> : <Trans>Save changes</Trans>}
</Button>
Expand Down
Loading
Loading