agentsclimarketplace

Create infrastructure

Skill anoopsg/agent_rules/src/exclusive/skills/create-infrastructure

Behavioral blueprints for agents.

Install
npx -y skills add anoopsg/agent_rules --skill create-infrastructure

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Creates new domains in the infrastructure layer using dart_mappable for models, Chopper for networking, and Riverpod for repositories. Use when the user asks to create a repository, API service, data model, or set up new infrastructure components.

SKILL.md

4.0 KB, as published. Nobody here has run it

Infrastructure Creation Skill

This skill defines the process for creating a new domain in the infrastructure/ layer, covering models, networking, and repositories.

1. Directory Structure

Infrastructure is organized by domain in lib/src/infrastructure/:

lib/src/infrastructure/my_domain/
├── models/             # DTOs and Domain Models
│   └── user_model.dart # Uses dart_mappable
├── services/           # Remote API definitions (Chopper)
│   └── my_service.dart
├── my_repository.dart  # Business logic interface
└── my_domain.dart      # Barrel file

2. Data Modeling (dart_mappable)

Always use @MappableClass() for models to get built-in JSON conversion and equality. Models must be immutable.

@MappableClass()
class UserProfile with UserProfileMappable {
  const UserProfile({
    required this.id,
    required this.email,
  });

  final String id;
  final String email;
}

3. Networking (Chopper)

Define API services as abstract classes extending ChopperService. Use apiClient to consume them.

3.1 Define the Service

@ChopperApi()
abstract class MyService extends ChopperService {
  static MyService create([ChopperClient? client]) => _$MyService(client);

  @GET(path: '/profile')
  Future<Response<UserProfile>> getProfile();
}

3.2 Register the Service

Add the service to apiClient in lib/src/infrastructure/_clients/api_client.dart:

@Riverpod(keepAlive: true)
ApiClient apiClient(Ref ref) {
  return ApiClient(
    services: [
      MyService.create(), // Register here
    ],
  );
}

4. Repositories

Repositories bridge the gap between clients (API, Storage) and the Features.

  • Rule: NEVER import from src/features/ into src/infrastructure/.
  • Pattern: Return Result<T, Failure> for operations that can fail.

4.1 Define Error Codes & Failures

Errors are centralized. You must define a technical code and its translation.

  1. Register the Code in lib/src/infrastructure/error_codes.dart:
enum AppErrorCode implements ErrorCode {
  myFeature404('myFeature404'), // Key in i18n
  // ...
}
  1. Add Translations under the errors key in lib/i18n/*.i18n.json for ALL locales:
// en.i18n.json
"errors": {
  "myFeature404": "The requested resource was not found."
}

// ar.i18n.json
"errors": {
  "myFeature404": "لم يتم العثور على المورد المطلوب."
}
  1. Generate Translations: Run the following command to sync the JSON changes with the Dart code:
melos run translate
  1. Define the Failure:
final class MyApiFailure extends Failure {
  const MyApiFailure({super.error}) : super(code: AppErrorCode.myFeature404);
}

4.2 Implementation

class MyRepository {
  MyRepository({required MyService service}) : _service = service;
  final MyService _service;

  Future<Result<UserProfile, Failure>> getProfile() async {
    try {
      final response = await _service.getProfile();
      if (response.isSuccessful) return Ok(response.body!);
      return Err(MyApiFailure(error: response.error));
    } catch (e) {
      return Err(MyApiFailure(error: e));
    }
  }
}

5. Riverpod Integration

Provide the repository via a global provider. Obtain the required service from the apiClientProvider.

@Riverpod(keepAlive: true)
MyRepository myRepository(Ref ref) {
  final service = ref.watch(apiClientProvider).getService<MyService>();
  return MyRepository(service: service);
}

6. Persistence

Use StorageClient for general persistence or SecureStorageClient for sensitive data (tokens). Always use AppKeys for storage keys.

final storage = ref.watch(storageClientProvider);
await storage.write(AppKeys.settings, 'value');

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.