AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Create Feature

skill-anoopsg-agent-rules-create-feature · by anoopsg

Use when asked to create a new feature or sub-feature following the DDD-lite architecture, or set up state, view, and page layers for a domain.

No reviews yet
0 installs
21 views
0.0% view→install

Install

$ agentstack add skill-anoopsg-agent-rules-create-feature

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-anoopsg-agent-rules-create-feature)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Create Feature? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Feature Creation Skill

This skill outlines the standard process for creating a new feature in the project, following the DDD-lite architecture. This guide covers both simple domains (like Settings) and complex domains (like Auth).

1. Directory Structure

Features are located in lib/src/features/. The structure depends on the complexity of the domain.

A. Simple Domain (e.g., Settings, Explore)

If the feature is self-contained and doesn't require separate sub-modules, keep it flat under the feature root folder. No _self folder is used.

lib/src/features/settings/
├── state/               # Domain-specific state
│   └── settings_notifier.dart
├── view/                # UI implementation
│   ├── settings_page.dart       # Entry point & Bindings
│   ├── settings_view.dart       # Mobile UI
│   └── settings_view_web.dart   # Web UI
└── settings.dart        # Feature barrel file

B. Complex Domain (e.g., Auth, Account)

If the feature has multiple sub-domains, it is structured as a complex domain. The _self folder is used for root-level domain control, shared domain state (e.g., auth status, user metadata, cache), and layout/shell views that host or wrap the sub-features.

Example: Auth Domain
lib/src/features/auth/
├── _self/               # Shared domain logic & state
│   └── state/
│       └── auth_notifier.dart  # Global auth status
├── login/               # Sub-domain feature
│   ├── state/           # Local feature state
│   │   └── login_notifier.dart
│   ├── view/            # Local UI
│   │   ├── login_page.dart
│   │   ├── login_view.dart
│   │   └── login_view_web.dart
│   └── login.dart       # Sub-domain barrel
└── auth.dart            # Domain barrel (exports _self and sub-domains)

2. Naming Conventions

| Entity | Convention | Example | | :--- | :--- | :--- | | Folder | snake_case | auth_login | | File | snake_case | login_page.dart | | Page Class | PascalCase + Page | LoginPage | | View Class | PascalCase + View | LoginView | | Web View Class | PascalCase + ViewWeb | LoginViewWeb | | Props Class | PascalCase + Props | LoginProps |

3. Creating the View Layer

3.1 The Page & Bindings

The Page widget delegates logic to _Bindings, which prepares the ViewProps.

class MyFeaturePage extends StatelessWidget {
  const MyFeaturePage({super.key});

  @override
  Widget build(BuildContext context) {
    return _Bindings(
      viewBuilder: (_, props) {
        // Simple pages can return the view directly.
        // Complex UIs should use MemoizedView for performance.
        if (isComplex) {
          return MemoizedView(
            props: props,
            builder: (context, memProps) => kIsWeb 
              ? MyFeatureViewWeb(props: memProps) 
              : MyFeatureView(props: memProps),
          );
        }

        return kIsWeb 
          ? MyFeatureViewWeb(props: props) 
          : MyFeatureView(props: props);
      },
    );
  }
}

3.2 ViewProps & Stale Closures

ViewProps separates Data (used for equality) from Callbacks (ignored for equality).

> [!IMPORTANT] > CRITICAL RULE FOR AI: NEVER include callback functions (like VoidCallback, Function, etc.) in the equalityProperties list of a ViewProps subclass. The base class has a runtime assertion that will crash the app if functions are included. ONLY include data fields.

> [!CAUTION] > STALE CLOSURES: Because MemoizedView ignores callbacks in equality > checks, your UI might hold a reference to an "old" closure. > Never capture variables from ref.watch in a callback. Always use > ref.read inside the closure to ensure you have the fresh state.

final class MyProps extends ViewProps {
  const MyProps({required this.data, required this.onAction});
  final String data;
  final VoidCallback onAction;

  // CRITICAL: Only include data fields. Do NOT include functions/callbacks here!
  @override
  List get equalityProperties => [data]; // Exclude onAction
}

// ... inside _Bindings ...
return viewBuilder(
  context,
  MyProps(
    data: ref.watch(myProvider).data, // Data for equality
    onAction: () {
      // SAFE: ref.read ensures fresh state when callback is executed
      ref.read(myProvider.notifier).doSomething(); 
      
      // DANGEROUS: capturing 'data' here will cause stale closure bugs
      // print(data); 
    },
  ),
);

3.3 Feature State & Notifiers

Feature state and notifiers live in the state/ directory of a feature.

  • State Location: Define the state class in the same file as the provider

or notifier. Do not create a separate file for the state class.

  • Data Modeling: Always use dart_mappable (@MappableClass()) for state

classes to get built-in immutability (copyWith) and equality.

import 'package:dart_mappable/dart_mappable.dart';
import 'package:framework/framework.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'login_notifier.mapper.dart';
part 'login_notifier.g.dart';

/// Local form state tracking for the Auth flow.
@MappableClass()
class LoginState with LoginStateMappable implements FailureInterface {
  const LoginState({this.isLoggingIn = false, this.failure});

  factory LoginState.loading() => const LoginState(isLoggingIn: true);

  final bool isLoggingIn;

  @override
  final Failure? failure;
}

@riverpod
class LoginNotifier extends _$LoginNotifier {
  @override
  LoginState build() => const LoginState();

  void login() {
    state = LoginState.loading();
    // Action logic here...
  }
}

4. Routing

Follow the [Routing Management Skill](manage-routes.md) to define the route class and register it in the appropriate group (open, unauthenticated, or authenticated).

5. Barrel Files (Exports)

  1. Sub-domain level: Export the notifier and the page.
  2. Domain level: Export _self and all sub-domain barrels.
  3. Global level (features/features.dart): Export all domain barrels.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.