-
-
Notifications
You must be signed in to change notification settings - Fork 321
docs: add Claude Code plugin with MobX.dart agent skills #1075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
amondnet
wants to merge
2
commits into
mobxjs:main
Choose a base branch
from
amondnet:feat/claude-plugin
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "name": "mobx-dart", | ||
| "owner": { | ||
| "name": "MobX.dart Contributors" | ||
| }, | ||
| "metadata": { | ||
| "description": "Claude Code plugins for MobX.dart — reactive state management for Dart and Flutter", | ||
| "version": "1.0.0", | ||
| "pluginRoot": "." | ||
| }, | ||
| "plugins": [ | ||
| { | ||
| "name": "mobx-dart", | ||
| "version": "2.6.0", | ||
| "description": "MobX.dart agent skills — observables, actions, reactions, Observer widget, store patterns, and code generation", | ||
| "source": "." | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "name": "mobx-dart", | ||
| "version": "2.6.0", | ||
| "description": "MobX.dart agent skills for Claude Code — reactive state management with observables, actions, reactions, and Flutter integration", | ||
| "author": { | ||
| "name": "MobX.dart Contributors", | ||
| "url": "https://github.com/mobxjs/mobx.dart" | ||
| }, | ||
| "homepage": "https://mobx.netlify.app", | ||
| "repository": "https://github.com/mobxjs/mobx.dart", | ||
| "license": "MIT", | ||
| "keywords": ["dart", "flutter", "mobx", "state-management", "reactive"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| --- | ||
| slug: /guides/working-with-ai | ||
| title: Working with AI | ||
| --- | ||
|
|
||
| import { PubBadge } from '../../src/components/Shield'; | ||
|
|
||
| AI coding assistants like Claude Code, GitHub Copilot, and Cursor can be powerful | ||
| allies when building MobX.dart applications. This guide covers tips for getting | ||
| the most out of AI tools with MobX. | ||
|
|
||
| ## Tips for Prompting AI | ||
|
|
||
| ### Be Explicit About the MobX Triad | ||
|
|
||
| When asking AI to create stores, mention the specific MobX concepts you want: | ||
|
|
||
| - **"Create a store with `@observable` fields, `@computed` getters, and `@action` methods"** | ||
| - **"Add a `reaction` that validates the email field when it changes"** | ||
| - **"Wrap the counter display in an `Observer` widget"** | ||
|
|
||
| AI tools work best when you use MobX-specific terminology rather than generic | ||
| descriptions. | ||
|
|
||
| ### Remind AI About Code Generation | ||
|
|
||
| MobX.dart relies on `mobx_codegen`. When asking AI to create a store, remind it | ||
| about the boilerplate: | ||
|
|
||
| ```dart | ||
| // Include the part directive and class structure | ||
| import 'package:mobx/mobx.dart'; | ||
|
|
||
| part 'counter.g.dart'; | ||
|
|
||
| class Counter = _Counter with _$Counter; | ||
|
|
||
| abstract class _Counter with Store { | ||
| // ... store body | ||
| } | ||
| ``` | ||
|
|
||
| ### Common Pitfalls to Watch For | ||
|
|
||
| When reviewing AI-generated MobX code, watch for these issues: | ||
|
|
||
| 1. **Missing `part` directive** — AI may forget `part 'filename.g.dart';` | ||
| 2. **Deep observability assumption** — AI may assume nested objects are automatically | ||
| tracked. Dart MobX does **not** support deep observability. | ||
| 3. **Observer tracking scope** — AI may place observable reads inside nested | ||
| functions within `Observer.builder`, where they won't be tracked. | ||
| 4. **Plain collections** — AI may use `List<T>` instead of `ObservableList<T>` | ||
| when item-level tracking is needed. | ||
|
|
||
| ## Agent Skills | ||
|
|
||
| This repository includes [Agent Skills](https://agentskills.io) that give AI | ||
| coding assistants deep knowledge of MobX.dart APIs, patterns, and best practices. | ||
| Skills work with Claude Code, Cursor, Windsurf, and other AI tools that support them. | ||
|
|
||
| ### Installation | ||
|
|
||
| ```bash | ||
| npx skills add mobxjs/mobx.dart | ||
| ``` | ||
|
|
||
| Target a specific agent with `--agent`: | ||
|
|
||
| ```bash | ||
| npx skills add mobxjs/mobx.dart --agent cursor | ||
| npx skills add mobxjs/mobx.dart --agent claude-code | ||
| ``` | ||
|
|
||
| Or install globally so the skill is available across all your projects: | ||
|
|
||
| ```bash | ||
| npx skills add mobxjs/mobx.dart --global | ||
| ``` | ||
|
|
||
| For Claude Code, you can also install via the plugin system: | ||
|
|
||
| ``` | ||
| /plugin marketplace add mobxjs/mobx.dart | ||
| /plugin install mobx-dart@mobx-dart | ||
| ``` | ||
|
|
||
| ### What's Included | ||
|
|
||
| The `mobx-dart` skill covers: | ||
|
|
||
| - **Core APIs** — Store class pattern, `@observable`, `@computed`, `@action`, `@readonly`, | ||
| code generation with <PubBadge name="mobx_codegen" /> | ||
| - **Reactions** — `autorun`, `reaction`, `when`, `asyncWhen`, custom schedulers | ||
| - **Flutter Integration** — `Observer` widget, `Observer.withBuiltChild`, `ReactionBuilder` | ||
| - **Reactive Collections** — `ObservableList`, `ObservableMap`, `ObservableSet`, | ||
| `ObservableFuture`, `ObservableStream`, `Atom` | ||
| - **Best Practices** — Widget-Store-Service triad, store organization, reactivity rules, | ||
| JSON serialization | ||
| - **Advanced** — `ReactiveContext`, `ReactiveConfig`, read/write policies, Spy debugging | ||
|
|
||
| ## Custom Instructions for AI Tools | ||
|
|
||
| If your AI tool supports custom instructions (e.g., `.cursorrules`, `CLAUDE.md`, | ||
| `.github/copilot-instructions.md`), consider adding MobX-specific guidance: | ||
|
|
||
| ```markdown | ||
| ## MobX.dart Conventions | ||
|
|
||
| - Use `mobx_codegen` annotations (`@observable`, `@computed`, `@action`) | ||
| - Always include `part 'filename.g.dart';` in store files | ||
| - Use `ObservableList`/`ObservableMap`/`ObservableSet` for reactive collections | ||
| - Wrap UI in `Observer` widget and read observables in immediate builder context | ||
| - Follow Widget-Store-Service triad for architecture | ||
| - Do not mutate observables outside of actions | ||
| ``` | ||
|
|
||
| This ensures consistent, correct MobX code regardless of which AI tool you use. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Generation Info | ||
|
|
||
| - **Source:** `sources/mobx.dart` | ||
| - **Git SHA:** `39a1f18c2e76a564b5e5358426d335569bc332ec` | ||
| - **Generated:** 2026-03-30 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| --- | ||
| name: mobx-dart | ||
| description: >- | ||
| This skill should be used when working with MobX.dart for Dart/Flutter state management, | ||
| when the user asks to "create a store", "add observable", "add action", "add computed", | ||
| "use Observer widget", "set up reactions", "organize stores", | ||
| or when code imports `package:mobx/mobx.dart`, `package:flutter_mobx/flutter_mobx.dart`, | ||
| or `package:mobx_codegen/mobx_codegen.dart`. | ||
| Covers observables, actions, reactions, Observer widget, store patterns, | ||
| code generation with mobx_codegen, and reactive collections. | ||
| --- | ||
|
|
||
| # MobX.dart | ||
|
|
||
| MobX.dart is a reactive state management library for Dart and Flutter built around three core concepts: **Observables** (reactive state), **Actions** (state mutations), and **Reactions** (side-effects). It uses `mobx_codegen` for annotation-based code generation to minimize boilerplate. | ||
|
|
||
| ## Packages | ||
|
|
||
| | Package | Purpose | | ||
| |---------|---------| | ||
| | `mobx` | Core library: Observables, Actions, Reactions | | ||
| | `flutter_mobx` | Flutter integration: Observer widget, ReactionBuilder | | ||
| | `mobx_codegen` | Code generation: `@observable`, `@computed`, `@action` annotations | | ||
|
|
||
| ## Store Declaration Pattern | ||
|
|
||
| Every store follows this boilerplate: | ||
|
|
||
| ```dart | ||
| import 'package:mobx/mobx.dart'; | ||
|
|
||
| part 'counter.g.dart'; | ||
|
|
||
| class Counter = _Counter with _$Counter; | ||
|
|
||
| abstract class _Counter with Store { | ||
| @observable | ||
| int value = 0; | ||
|
|
||
| @computed | ||
| bool get isPositive => value > 0; | ||
|
|
||
| @action | ||
| void increment() { | ||
| value++; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Run code generation with: | ||
| ```bash | ||
| flutter pub run build_runner watch --delete-conflicting-outputs | ||
| ``` | ||
|
|
||
| ## Key Annotations | ||
|
|
||
| | Annotation | Target | Purpose | | ||
| |---|---|---| | ||
| | `@observable` | Field | Make field reactive | | ||
| | `@readonly` | Private field | Observable with auto-generated public getter; mutations only via `@action` | | ||
| | `@computed` | Getter | Derived state that auto-updates when dependencies change | | ||
| | `@action` | Method | Wrap mutations in a transaction; supports async | | ||
| | `@MakeObservable()` | Field | Advanced config (e.g., `useDeepEquals: true`) | | ||
|
|
||
| ## Observer Widget | ||
|
|
||
| Wrap reactive UI in `Observer` from `flutter_mobx`: | ||
|
|
||
| ```dart | ||
| Observer(builder: (_) => Text('${counter.value}')) | ||
| ``` | ||
|
|
||
| **Critical**: Only observables read in the **immediate execution context** of the builder are tracked. Observables read inside nested functions or callbacks are NOT tracked. | ||
|
|
||
| ## Reactive Collections | ||
|
|
||
| Use `ObservableList`, `ObservableMap`, `ObservableSet` instead of plain Dart collections for item-level tracking. Use `ObservableFuture` and `ObservableStream` for async state. | ||
|
|
||
| ## Reference Files | ||
|
|
||
| For detailed API documentation, patterns, and best practices, consult: | ||
|
|
||
| ### Core | ||
|
|
||
| - **[`references/core-store-and-codegen.md`](references/core-store-and-codegen.md)** — Store class pattern, annotations, build_runner, generated output | ||
| - **[`references/core-observables.md`](references/core-observables.md)** — Observable, Computed, @observable, @readonly, @computed, reactive extensions | ||
| - **[`references/core-actions.md`](references/core-actions.md)** — @action, runInAction, untracked, transaction, async actions | ||
| - **[`references/core-reactions.md`](references/core-reactions.md)** — autorun, reaction, when, asyncWhen, custom schedulers | ||
|
|
||
| ### Flutter Integration | ||
|
|
||
| - **[`references/features-observer-widget.md`](references/features-observer-widget.md)** — Observer, Observer.withBuiltChild, ReactionBuilder | ||
| - **[`references/features-reactive-collections.md`](references/features-reactive-collections.md)** — ObservableList/Map/Set/Future/Stream, Atom | ||
|
|
||
| ### Best Practices | ||
|
|
||
| - **[`references/best-practices-store-organization.md`](references/best-practices-store-organization.md)** — Widget-Store-Service triad, store hierarchy, Provider integration | ||
| - **[`references/best-practices-reactivity-rules.md`](references/best-practices-reactivity-rules.md)** — When MobX reacts, tracking pitfalls, form validation | ||
| - **[`references/best-practices-json-serialization.md`](references/best-practices-json-serialization.md)** — json_serializable integration, custom converters | ||
|
|
||
| ### Advanced | ||
|
|
||
| - **[`references/advanced-context-and-config.md`](references/advanced-context-and-config.md)** — ReactiveContext, ReactiveConfig, read/write policies | ||
| - **[`references/advanced-spy.md`](references/advanced-spy.md)** — Spy API for tracing and debugging reactive events | ||
|
|
||
| ## Important Notes | ||
|
|
||
| - **No deep observability**: Unlike JS MobX, marking a complex object as `@observable` only tracks reference reassignment, not internal field changes. Mark individual fields with `@observable`. | ||
| - **Action enforcement**: By default, mutating an observed observable outside an action throws. Single-property setters in codegen stores are auto-wrapped. | ||
| - **Computed caching**: `.value` always re-evaluates, but notifications only fire when the result differs from the previous value. |
72 changes: 72 additions & 0 deletions
72
skills/mobx-dart/references/advanced-context-and-config.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| --- | ||
| name: advanced-context-and-config | ||
| description: ReactiveContext and ReactiveConfig for custom MobX contexts, read/write policies, and error boundaries | ||
| --- | ||
|
|
||
| # ReactiveContext and Configuration | ||
|
|
||
| MobX operates within a `ReactiveContext` that manages observables and reactions. By default, the singleton `mainContext` is used. Custom contexts are an advanced feature for isolating reactive systems. | ||
|
|
||
| ## ReactiveContext | ||
|
|
||
| Create a custom context for isolated reactivity (e.g., a library using MobX internally that shouldn't share context with the host app): | ||
|
|
||
| ```dart | ||
| final myContext = ReactiveContext(config: ReactiveConfig( | ||
| writePolicy: ReactiveWritePolicy.always, | ||
| )); | ||
|
|
||
| final counter = Observable(0, context: myContext); | ||
| ``` | ||
|
|
||
| ## ReactiveConfig | ||
|
|
||
| ```dart | ||
| ReactiveConfig({ | ||
| bool disableErrorBoundaries = false, | ||
| ReactiveWritePolicy writePolicy = ReactiveWritePolicy.observed, | ||
| ReactiveReadPolicy readPolicy = ReactiveReadPolicy.never, | ||
| int maxIterations = 100, | ||
| }) | ||
| ``` | ||
|
|
||
| ### Write Policy | ||
|
|
||
| Controls enforcement of mutations inside actions: | ||
|
|
||
| | Policy | Behavior | | ||
| |---|---| | ||
| | `observed` (default) | Throws only if the mutated observable is currently being observed | | ||
| | `always` | Always requires mutations inside an action | | ||
| | `never` | No enforcement (discouraged) | | ||
|
|
||
| ### Read Policy | ||
|
|
||
| Controls enforcement of reading observables inside reactive contexts: | ||
|
|
||
| | Policy | Behavior | | ||
| |---|---| | ||
| | `never` (default) | Reads allowed anywhere | | ||
| | `always` | Reads must happen inside an Action or Reaction | | ||
|
|
||
| ### Error Boundaries | ||
|
|
||
| `disableErrorBoundaries: true` makes MobX not catch exceptions in reactions (useful for debugging). Default is `false` — MobX catches and logs unhandled exceptions. | ||
|
|
||
| ### Max Iterations | ||
|
|
||
| `maxIterations` (default: 100) limits reaction cycles. If reactions keep triggering more reactions beyond this limit, MobX throws to prevent infinite loops from cyclical dependencies. | ||
|
|
||
| ## Modifying mainContext | ||
|
|
||
| ```dart | ||
| mainContext.config = mainContext.config.clone( | ||
| writePolicy: ReactiveWritePolicy.always, | ||
| isSpyEnabled: true, | ||
| ); | ||
| ``` | ||
|
|
||
| <!-- | ||
| Source references: | ||
| - https://mobx.netlify.app/api/context | ||
| --> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this part is not necessarily true for every project. Some projects rely purely on raw observables rather than using codegen, so we should not make it a mandate that everyone has to go through codegen.