command-handle-implementation
Implement command handles for the current feature
- License 许可
- MIT
- 最近更新
- 2026-10-28
- Stars
- ★ 1
- Forks
- 0
01 前言 Front Matter
- name
- command-handle-implementation
- description
- Implement command handles for the current feature
03 SKILL.md 正文
Command Handle Implementation
When to use
Use this skill whenever you need to create or modify a command Handle — the component responsible for registering command.handle() listeners.
This includes:
- Creating a new Handle.
- Adding an action to an existing Handle.
- Refactoring an existing Handle.
Do not use this skill for general command architecture questions or command dispatching. Follow the command-bus-architecture skill instead.
If src/lib/command/ does not exist, invoke the setup-command-system skill before implementing the Handle.
Before implementation
- Identify the domain/feature that owns the Handle.
- Confirm whether the action is
ActionorScopedAction. - Check whether the action declaration already exists.
- Check whether a Handle already exists for the domain.
Do not change the action scope or architecture merely to simplify the implementation.
File structure
Shared application context:
src/components/handles/<domain>/
├── <domain>-actions.ts
└── <domain>-handle.tsx
Feature context:
src/features/<feature>/components/handles/<domain>/
├── <domain>-actions.ts
└── <domain>-handle.tsx
Action declarations
If the action is new:
- Declare its type in
<domain>-actions.ts. - Extend
#/lib/command/globalthrough module augmentation. - Use
Actionfor global actions. - Use
ScopedActionfor instance-specific actions. - Never modify the global
Actionsinterface directly.
If the action already exists, reuse its existing declaration. Do not redeclare it.
Handle implementation
Handler functions MUST:
- Be defined inside the component.
- Be defined outside
useEffect. - Contain the application/orchestration logic.
- Call store mutations when state needs to change.
- Call external APIs when required.
- Dispatch other commands when required.
Example:
export function MyHandle() {
async function handleDoThing(payload: Payload) {
const result = await api.process(payload);
myStore.setData(result);
}
useEffect(() => {
const disposes = [
command.handle("myDomain.doThing", handleDoThing),
];
return () => {
for (const dispose of disposes) dispose();
};
}, []);
return null;
}
Registration
command.handle() MUST:
- Be called inside
useEffect. - Receive handlers by reference.
- Receive
{ instanceId }when registering aScopedAction. - Return a disposer that is cleaned up.
Do not put handler logic inline:
// ❌ Wrong
command.handle("myDomain.doThing", async (payload) => {
// logic
});
Use a named handler instead:
// ✅ Correct
async function handleDoThing(payload: Payload) {
// logic
}
command.handle("myDomain.doThing", handleDoThing);
Cleanup
Store every disposer returned by command.handle().
Dispose every handler when the Handle unmounts.
useEffect(() => {
const disposes = [
command.handle("domain.action", handleAction),
command.handle("domain.otherAction", handleOtherAction),
];
return () => {
for (const dispose of disposes) dispose();
};
}, []);
Dependencies
Use the correct useEffect dependencies.
If handlers close over a stable store reference and dependencies intentionally need to be omitted, use:
// biome-ignore lint/correctness/useExhaustiveDependencies: handlers close over the stable store reference
Always provide a clear reason for the suppression.
Store and Dispatching
Store rules, the Store/Handle split and dispatching rules are defined in command-bus-architecture. In a Handle:
- Change state only through store setters.
- Read derived values from the store (
store.$value); never compute them in the Handle. - Dispatch through the
actionsproxy;command.dispatch()only for external/realtime/AI triggers.
Verification
Before finishing:
- [ ] Typecheck and lint pass (repository scripts from
epic-discover-repository). - [ ] Handlers are outside
useEffect. - [ ]
command.handle()receives handlers by reference. - [ ] All disposers are cleaned up.
- [ ] Scoped actions receive the correct
instanceId. - [ ] New actions use module augmentation.
- [ ] Existing actions are not redeclared.
- [ ] MobX store contains state, setters and
$derived values only; no execution logic. - [ ] The Handle computes no derived values.
- [ ] Normal dispatch uses the
actionsproxy. - [ ] No unnecessary
command.dispatch()is used.
04 同仓库更多 Skills
utils-implementation
Write and organize utils (pure helpers for formatting, mapping, filtering, math, parsing, ids, storage) as one namespace object per domain with clear, readable names. Use before creating or changing any util.
test-writer
Write tests for the current implementation
tech-lead
Analyze a project, turn the user's goal into an implementation-ready GitHub Epic and Issues (following project rules, the Command Bus architecture and Fragiola UI), then start epic-implementer automatically (use the no-implement flag to stop after planning).
tech-lead-publish
Publish a final Epic and its Issues to GitHub, linked and labeled, keeping dependency and execution information. Sub-skill of tech-lead.
setup-command-system
Install the Command System architecture in the project
reviewer
Review code changes and provide feedback