[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6P4VYV6F2P2VBF5WVZXTRDV":3,"skill-same:01M6P4VYV6F2P2VBF5WVZXTRDV":66},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":50,"updatedAt":51,"install":52,"resources":65},"01M6P4VYV6F2P2VBF5WVZXTRDV","command-bus-architecture",null,"The mandatory application architecture - every interaction is a Command Bus action, all state and derived values live in MobX stores, all execution logic lives in Handles, components only read and present. Use before planning, implementing or reviewing any application code.","maurodesouza\u002Fai-kanban-app-lab","maurodesouza","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F54520907?v=4","01M6P3VA3WVQC4XZ0RQWJCDKW6","Mauro de Souza","01M6P3VA7YK770SNWT12GBEGAF",1,"MIT","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Fcommand-bus-architecture\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"architecture","command bus architecture","command","logic","components","implementing","values","action","mobx","interaction","present","live","planning","application","only","use","read","code","execution","state","2026-11-10 10:12:30",false,"---\nname: command-bus-architecture\ndescription: The mandatory application architecture - every interaction is a Command Bus action, all state and derived values live in MobX stores, all execution logic lives in Handles, components only read and present. Use before planning, implementing or reviewing any application code.\n---\n\n# User Input\n\n```text\n$ARGUMENTS\n```\n\n# Objective\n\nDefine how application code must be written in this project.\n\nThis skill is the source of truth for architecture decisions made by `epic-plan-execution`, `epic-execution`, `command-handle-implementation`, `test-writer` and `reviewer`.\n\nThe Command Bus used is **V2** (installed by `setup-command-system`). Do not use V3.\n\n# 1. Core Rules\n\n1. **Everything is an event.** Every application interaction is an action dispatched through the Command Bus and handled by a Handle.\n2. **Stores hold all state and all derived values.** Every `computed` lives in a MobX store. There is no derived logic outside stores.\n3. **Handles hold all execution logic.** Every decision, validation, request, side effect and orchestration lives in a Handle.\n4. **Components only read and present.** Components read values already prepared by the store and dispatch actions. They do not calculate, derive or choose what to show.\n\n| Layer | Responsible for |\n| --- | --- |\n| MobX Store | All state, all derived values \u002F `computed`, preparing every value the UI presents |\n| Handle (Command Bus) | All execution logic, event processing, operations, state changes |\n| Component | Reading store values and presenting them |\n\n# 2. What Goes Through the Command Bus\n\nAbsolutely everything, including:\n\n| Interaction | Example action |\n| --- | --- |\n| Open \u002F close modal | `modal.open`, `modal.close` |\n| Open \u002F close drawer | `drawer.open`, `drawer.close` |\n| Notifications | `notification.show`, `notification.dismiss` |\n| Navigation | `navigation.go`, `navigation.back` |\n| Forms | `\u003Cdomain>.form.submit`, `\u003Cdomain>.form.reset` |\n| Requests | `\u003Cdomain>.fetch`, `\u003Cdomain>.create`, `\u003Cdomain>.update`, `\u003Cdomain>.delete` |\n| Toggles | `\u003Cdomain>.\u003Cthing>.toggle` |\n| Any other interaction | `\u003Cdomain>.\u003Cverb>` |\n\nIf a component needs something to happen, it dispatches an action. It never does it itself.\n\n# 3. Actions\n\n* Declared in `\u003Cdomain>-actions.ts`, next to the `\u003Cdomain>-handle.tsx`, through module augmentation of `#\u002Flib\u002Fcommand\u002Fglobal`.\n* `Action` for global actions, `ScopedAction` for instance-specific actions.\n* Never edit the global `Actions` interface directly.\n\n# 4. Store (MobX)\n\nThe store holds **all state** and **all derived values**. It holds **no execution logic**.\n\n## Structure\n\nOrganize the class in this order, with `#region` blocks:\n\n1. `Primitives` - observable state fields.\n2. `Actions` - setters.\n3. `Derived primitives` - small `$` getters over primitives.\n4. `Data` - `$` getters that shape data (lists, aggregates, series).\n5. `UI` - one `$\u003Cpart>UI` getter per component\u002Fpart, returning everything that part presents.\n\nAlways call `makeAutoObservable(this, {}, { autoBind: true })` in the constructor.\n\n## Naming: `$` prefix\n\n**Every derived value starts with `$`**: `$` + name.\n\n`$isVisible`, `$title`, `$description`, `$buttonLabel`, `$hasData`, `$status`, `$toggleUI`.\n\nPrimitives and setters never start with `$`.\n\n## Allowed\n\n* Observable primitive fields.\n* Setters that only assign (`setX(x) { this.x = x }`), push, update or reset state.\n* `$` getters computing any derived value, including all presentation values (texts, labels, variants, flags, formatted values, statuses, lists ready to render).\n* Pure helper functions imported from `utils\u002F` (written with `utils-implementation`) and used inside `$` getters (formatting, math, mapping).\n\n## Forbidden\n\n* API calls or any async work.\n* Dispatching actions.\n* Side effects (timers, storage, navigation, notifications, logging).\n* Coordinating multiple state changes based on business rules inside setters (e.g. \"if start > end then move end\"). That decision belongs to the Handle, which calls the setters.\n* Calling other stores.\n\n## Example\n\n```typescript\n\u002F\u002F src\u002Ffeatures\u002Fsettings\u002Fstore\u002Fstore.ts\nimport { makeAutoObservable } from \"mobx\";\n\nexport class SettingsStore {\n  \u002F\u002F #region Primitives\n  isNotificationsEnabled = false;\n  \u002F\u002F #endregion\n\n  constructor() {\n    makeAutoObservable(this, {}, { autoBind: true });\n  }\n\n  \u002F\u002F #region Actions\n  setIsNotificationsEnabled(value: boolean) {\n    this.isNotificationsEnabled = value;\n  }\n  \u002F\u002F #endregion\n\n  \u002F\u002F #region UI\n  get $notificationsToggleUI() {\n    const enabled = this.isNotificationsEnabled;\n\n    return {\n      checked: enabled,\n      label: enabled ? \"Notifications on\" : \"Notifications off\",\n      description: enabled\n        ? \"You will receive updates about your boards.\"\n        : \"You will not receive any updates.\",\n      buttonLabel: enabled ? \"Disable\" : \"Enable\",\n    };\n  }\n  \u002F\u002F #endregion\n}\n\nexport const settingsStore = new SettingsStore();\n```\n\n## Global vs scoped stores\n\n* Global store: export a single instance (`export const settingsStore = new SettingsStore()`) and a `use-\u003Cfeature>.ts` hook that returns it.\n* Scoped store (one per instance): create it once in the feature Provider (`useMemo(() => new Store(), [])`), expose it through context, read it with `use-\u003Cfeature>.ts` which throws when used outside the Provider. The store exposes its `id`, used as `instanceId` for scoped actions.\n\n# 5. Handle\n\nThe Handle holds all execution logic. Implement it with `command-handle-implementation`.\n\n* Calls APIs.\n* Validates and decides.\n* Changes state only through store setters.\n* Dispatches other actions through the `actions` proxy (e.g. `actions.notification.show(...)` after a failed request).\n* Handles errors: a failure becomes store state or another action, never an exception thrown to the component.\n* Sets loading primitives in the store (`try` \u002F `finally`) when the UI presents a loading state.\n\n```typescript\n\u002F\u002F src\u002Ffeatures\u002Fsettings\u002Fcomponents\u002Fhandles\u002Fsettings\u002Fsettings-handle.tsx\nexport function SettingsHandle() {\n  const store = useSettings();\n\n  async function handleToggleNotifications() {\n    const next = !store.isNotificationsEnabled;\n\n    store.setIsNotificationsEnabled(next);\n\n    try {\n      await api.settings.update({ notifications: next });\n    } catch {\n      store.setIsNotificationsEnabled(!next);\n      actions.notification.show({ type: \"error\", message: \"Could not save settings\" });\n    }\n  }\n\n  useEffect(() => {\n    const disposes = [\n      command.handle(\"settings.notifications.toggle\", handleToggleNotifications),\n    ];\n\n    return () => {\n      for (const dispose of disposes) dispose();\n    };\n  }, []);\n\n  return null;\n}\n```\n\nHandles are mounted once, as high as their context requires (app root for shared domains, feature root for feature domains, inside the Provider for scoped domains).\n\n# 6. Component\n\nA component only reads and presents.\n\n* Built with Fragiola UI (`fragiola-ui`).\n* Wrapped with `observer` from `mobx-react-lite`.\n* Gets the store through `use-\u003Cfeature>.ts`.\n* Destructures its `$\u003Cpart>UI` getter and renders the values as they are.\n* Dispatches through `actions`.\n\nForbidden in components:\n\n* Calculations, formatting, filtering, sorting, mapping data into new values.\n* Conditionals that choose texts, labels, variants or values from state (`enabled ? \"On\" : \"Off\"`).\n* `useMemo` \u002F derived values \u002F `computed`.\n* API calls, business logic, store mutation.\n* `useState` for application state (purely ephemeral visual state, such as hover, may stay local).\n\nConditional rendering is allowed only on a flag or status already prepared by the store (`if (!ui.isVisible) return null`, `switch (ui.status)`).\n\n```typescript\n\u002F\u002F ✅ Correct\nexport const NotificationsToggle = observer(() => {\n  const store = useSettings();\n  const { checked, label, description, buttonLabel } = store.$notificationsToggleUI;\n\n  return (\n    \u003CToggle\n      checked={checked}\n      label={label}\n      description={description}\n      buttonLabel={buttonLabel}\n      onClick={() => actions.settings.notifications.toggle()}\n    \u002F>\n  );\n});\n```\n\n```typescript\n\u002F\u002F ❌ Wrong - the component derives presentation values from state\nexport const NotificationsToggle = observer(() => {\n  const store = useSettings();\n  const label = store.isNotificationsEnabled ? \"Notifications on\" : \"Notifications off\";\n\n  return \u003CToggle label={label} \u002F>;\n});\n```\n\n# 7. File Structure\n\n```text\nsrc\u002Ffeatures\u002F\u003Cfeature>\u002F\n├── store\u002F\n│   ├── store.ts                       # MobX store\n│   └── store.test.ts                  # tests for $ derived values\n├── hooks\u002F\n│   └── use-\u003Cfeature>.ts               # returns the store\n├── utils\u002F                             # pure helpers used by $ getters\n└── components\u002F\n    ├── handles\u002F\u003Cdomain>\u002F\n    │   ├── \u003Cdomain>-actions.ts        # action declarations (module augmentation)\n    │   └── \u003Cdomain>-handle.tsx\n    └── ...                            # observer components\n```\n\nShared application domains (modal, drawer, notification, navigation) follow the same shape: `src\u002Fcomponents\u002Fhandles\u002F\u003Cdomain>\u002F` for actions + Handle, `src\u002Fstore\u002F\u003Cdomain>\u002Fstore.ts` for the store and `src\u002Fhooks\u002Fuse-\u003Cdomain>.ts` for the hook.\n\nA domain without state has no store. Do not create a store without observable state.\n\n# 8. Loading State\n\n* When the UI presents a loading state, the Handle sets a loading primitive in the store and the store exposes it through `$status` \u002F `$\u003Cpart>UI`.\n* `useTransition` is only used where no store value is involved, e.g. disabling the button that dispatched the action.\n\n# 9. Dispatching\n\n* Use the `actions` proxy: `actions.domain.action(payload)`.\n* Scoped: `actions.domain.action(payload, { instanceId: store.id })`.\n* `command.dispatch()` only for external triggers (realtime, WebSocket, server events, AI\u002Ftool triggers).\n\n# 10. Prerequisites\n\n* If `src\u002Flib\u002Fcommand\u002F` does not exist, run `setup-command-system` first.\n* If `mobx` \u002F `mobx-react-lite` are not installed, install them (verify versions with `epic-current-documentation`). MobX is part of this architecture and is pre-approved.\n\n# 11. Checklist\n\n* [ ] Every interaction is an action handled by a Handle.\n* [ ] All state lives in MobX stores.\n* [ ] All derived values \u002F `computed` live in stores; none in components, hooks or Handles.\n* [ ] Every derived value starts with `$`.\n* [ ] Each component reads a prepared `$\u003Cpart>UI` (or `$` value) and does no calculation or value selection.\n* [ ] Stores contain no execution logic (no async, no API, no dispatch, no side effects, no business decisions in setters).\n* [ ] Stores follow the region order and use `makeAutoObservable(this, {}, { autoBind: true })`.\n* [ ] Components reading stores are `observer`.\n* [ ] Errors are handled in Handles (state or `notification.show`).\n* [ ] Actions declared via module augmentation.\n* [ ] Dispatch uses the `actions` proxy.\n* [ ] Handles dispose every registration on unmount.\n","# User Input\n\n```text\n$ARGUMENTS\n```\n\n# Objective\n\nDefine how application code must be written in this project.\n\nThis skill is the source of truth for architecture decisions made by `epic-plan-execution`, `epic-execution`, `command-handle-implementation`, `test-writer` and `reviewer`.\n\nThe Command Bus used is **V2** (installed by `setup-command-system`). Do not use V3.\n\n# 1. Core Rules\n\n1. **Everything is an event.** Every application interaction is an action dispatched through the Command Bus and handled by a Handle.\n2. **Stores hold all state and all derived values.** Every `computed` lives in a MobX store. There is no derived logic outside stores.\n3. **Handles hold all execution logic.** Every decision, validation, request, side effect and orchestration lives in a Handle.\n4. **Components only read and present.** Components read values already prepared by the store and dispatch actions. They do not calculate, derive or choose what to show.\n\n| Layer | Responsible for |\n| --- | --- |\n| MobX Store | All state, all derived values \u002F `computed`, preparing every value the UI presents |\n| Handle (Command Bus) | All execution logic, event processing, operations, state changes |\n| Component | Reading store values and presenting them |\n\n# 2. What Goes Through the Command Bus\n\nAbsolutely everything, including:\n\n| Interaction | Example action |\n| --- | --- |\n| Open \u002F close modal | `modal.open`, `modal.close` |\n| Open \u002F close drawer | `drawer.open`, `drawer.close` |\n| Notifications | `notification.show`, `notification.dismiss` |\n| Navigation | `navigation.go`, `navigation.back` |\n| Forms | `\u003Cdomain>.form.submit`, `\u003Cdomain>.form.reset` |\n| Requests | `\u003Cdomain>.fetch`, `\u003Cdomain>.create`, `\u003Cdomain>.update`, `\u003Cdomain>.delete` |\n| Toggles | `\u003Cdomain>.\u003Cthing>.toggle` |\n| Any other interaction | `\u003Cdomain>.\u003Cverb>` |\n\nIf a component needs something to happen, it dispatches an action. It never does it itself.\n\n# 3. Actions\n\n* Declared in `\u003Cdomain>-actions.ts`, next to the `\u003Cdomain>-handle.tsx`, through module augmentation of `#\u002Flib\u002Fcommand\u002Fglobal`.\n* `Action` for global actions, `ScopedAction` for instance-specific actions.\n* Never edit the global `Actions` interface directly.\n\n# 4. Store (MobX)\n\nThe store holds **all state** and **all derived values**. It holds **no execution logic**.\n\n## Structure\n\nOrganize the class in this order, with `#region` blocks:\n\n1. `Primitives` - observable state fields.\n2. `Actions` - setters.\n3. `Derived primitives` - small `$` getters over primitives.\n4. `Data` - `$` getters that shape data (lists, aggregates, series).\n5. `UI` - one `$\u003Cpart>UI` getter per component\u002Fpart, returning everything that part presents.\n\nAlways call `makeAutoObservable(this, {}, { autoBind: true })` in the constructor.\n\n## Naming: `$` prefix\n\n**Every derived value starts with `$`**: `$` + name.\n\n`$isVisible`, `$title`, `$description`, `$buttonLabel`, `$hasData`, `$status`, `$toggleUI`.\n\nPrimitives and setters never start with `$`.\n\n## Allowed\n\n* Observable primitive fields.\n* Setters that only assign (`setX(x) { this.x = x }`), push, update or reset state.\n* `$` getters computing any derived value, including all presentation values (texts, labels, variants, flags, formatted values, statuses, lists ready to render).\n* Pure helper functions imported from `utils\u002F` (written with `utils-implementation`) and used inside `$` getters (formatting, math, mapping).\n\n## Forbidden\n\n* API calls or any async work.\n* Dispatching actions.\n* Side effects (timers, storage, navigation, notifications, logging).\n* Coordinating multiple state changes based on business rules inside setters (e.g. \"if start > end then move end\"). That decision belongs to the Handle, which calls the setters.\n* Calling other stores.\n\n## Example\n\n```typescript\n\u002F\u002F src\u002Ffeatures\u002Fsettings\u002Fstore\u002Fstore.ts\nimport { makeAutoObservable } from \"mobx\";\n\nexport class SettingsStore {\n  \u002F\u002F #region Primitives\n  isNotificationsEnabled = false;\n  \u002F\u002F #endregion\n\n  constructor() {\n    makeAutoObservable(this, {}, { autoBind: true });\n  }\n\n  \u002F\u002F #region Actions\n  setIsNotificationsEnabled(value: boolean) {\n    this.isNotificationsEnabled = value;\n  }\n  \u002F\u002F #endregion\n\n  \u002F\u002F #region UI\n  get $notificationsToggleUI() {\n    const enabled = this.isNotificationsEnabled;\n\n    return {\n      checked: enabled,\n      label: enabled ? \"Notifications on\" : \"Notifications off\",\n      description: enabled\n        ? \"You will receive updates about your boards.\"\n        : \"You will not receive any updates.\",\n      buttonLabel: enabled ? \"Disable\" : \"Enable\",\n    };\n  }\n  \u002F\u002F #endregion\n}\n\nexport const settingsStore = new SettingsStore();\n```\n\n## Global vs scoped stores\n\n* Global store: export a single instance (`export const settingsStore = new SettingsStore()`) and a `use-\u003Cfeature>.ts` hook that returns it.\n* Scoped store (one per instance): create it once in the feature Provider (`useMemo(() => new Store(), [])`), expose it through context, read it with `use-\u003Cfeature>.ts` which throws when used outside the Provider. The store exposes its `id`, used as `instanceId` for scoped actions.\n\n# 5. Handle\n\nThe Handle holds all execution logic. Implement it with `command-handle-implementation`.\n\n* Calls APIs.\n* Validates and decides.\n* Changes state only through store setters.\n* Dispatches other actions through the `actions` proxy (e.g. `actions.notification.show(...)` after a failed request).\n* Handles errors: a failure becomes store state or another action, never an exception thrown to the component.\n* Sets loading primitives in the store (`try` \u002F `finally`) when the UI presents a loading state.\n\n```typescript\n\u002F\u002F src\u002Ffeatures\u002Fsettings\u002Fcomponents\u002Fhandles\u002Fsettings\u002Fsettings-handle.tsx\nexport function SettingsHandle() {\n  const store = useSettings();\n\n  async function handleToggleNotifications() {\n    const next = !store.isNotificationsEnabled;\n\n    store.setIsNotificationsEnabled(next);\n\n    try {\n      await api.settings.update({ notifications: next });\n    } catch {\n      store.setIsNotificationsEnabled(!next);\n      actions.notification.show({ type: \"error\", message: \"Could not save settings\" });\n    }\n  }\n\n  useEffect(() => {\n    const disposes = [\n      command.handle(\"settings.notifications.toggle\", handleToggleNotifications),\n    ];\n\n    return () => {\n      for (const dispose of disposes) dispose();\n    };\n  }, []);\n\n  return null;\n}\n```\n\nHandles are mounted once, as high as their context requires (app root for shared domains, feature root for feature domains, inside the Provider for scoped domains).\n\n# 6. Component\n\nA component only reads and presents.\n\n* Built with Fragiola UI (`fragiola-ui`).\n* Wrapped with `observer` from `mobx-react-lite`.\n* Gets the store through `use-\u003Cfeature>.ts`.\n* Destructures its `$\u003Cpart>UI` getter and renders the values as they are.\n* Dispatches through `actions`.\n\nForbidden in components:\n\n* Calculations, formatting, filtering, sorting, mapping data into new values.\n* Conditionals that choose texts, labels, variants or values from state (`enabled ? \"On\" : \"Off\"`).\n* `useMemo` \u002F derived values \u002F `computed`.\n* API calls, business logic, store mutation.\n* `useState` for application state (purely ephemeral visual state, such as hover, may stay local).\n\nConditional rendering is allowed only on a flag or status already prepared by the store (`if (!ui.isVisible) return null`, `switch (ui.status)`).\n\n```typescript\n\u002F\u002F ✅ Correct\nexport const NotificationsToggle = observer(() => {\n  const store = useSettings();\n  const { checked, label, description, buttonLabel } = store.$notificationsToggleUI;\n\n  return (\n    \u003CToggle\n      checked={checked}\n      label={label}\n      description={description}\n      buttonLabel={buttonLabel}\n      onClick={() => actions.settings.notifications.toggle()}\n    \u002F>\n  );\n});\n```\n\n```typescript\n\u002F\u002F ❌ Wrong - the component derives presentation values from state\nexport const NotificationsToggle = observer(() => {\n  const store = useSettings();\n  const label = store.isNotificationsEnabled ? \"Notifications on\" : \"Notifications off\";\n\n  return \u003CToggle label={label} \u002F>;\n});\n```\n\n# 7. File Structure\n\n```text\nsrc\u002Ffeatures\u002F\u003Cfeature>\u002F\n├── store\u002F\n│   ├── store.ts                       # MobX store\n│   └── store.test.ts                  # tests for $ derived values\n├── hooks\u002F\n│   └── use-\u003Cfeature>.ts               # returns the store\n├── utils\u002F                             # pure helpers used by $ getters\n└── components\u002F\n    ├── handles\u002F\u003Cdomain>\u002F\n    │   ├── \u003Cdomain>-actions.ts        # action declarations (module augmentation)\n    │   └── \u003Cdomain>-handle.tsx\n    └── ...                            # observer components\n```\n\nShared application domains (modal, drawer, notification, navigation) follow the same shape: `src\u002Fcomponents\u002Fhandles\u002F\u003Cdomain>\u002F` for actions + Handle, `src\u002Fstore\u002F\u003Cdomain>\u002Fstore.ts` for the store and `src\u002Fhooks\u002Fuse-\u003Cdomain>.ts` for the hook.\n\nA domain without state has no store. Do not create a store without observable state.\n\n# 8. Loading State\n\n* When the UI presents a loading state, the Handle sets a loading primitive in the store and the store exposes it through `$status` \u002F `$\u003Cpart>UI`.\n* `useTransition` is only used where no store value is involved, e.g. disabling the button that dispatched the action.\n\n# 9. Dispatching\n\n* Use the `actions` proxy: `actions.domain.action(payload)`.\n* Scoped: `actions.domain.action(payload, { instanceId: store.id })`.\n* `command.dispatch()` only for external triggers (realtime, WebSocket, server events, AI\u002Ftool triggers).\n\n# 10. Prerequisites\n\n* If `src\u002Flib\u002Fcommand\u002F` does not exist, run `setup-command-system` first.\n* If `mobx` \u002F `mobx-react-lite` are not installed, install them (verify versions with `epic-current-documentation`). MobX is part of this architecture and is pre-approved.\n\n# 11. Checklist\n\n* [ ] Every interaction is an action handled by a Handle.\n* [ ] All state lives in MobX stores.\n* [ ] All derived values \u002F `computed` live in stores; none in components, hooks or Handles.\n* [ ] Every derived value starts with `$`.\n* [ ] Each component reads a prepared `$\u003Cpart>UI` (or `$` value) and does no calculation or value selection.\n* [ ] Stores contain no execution logic (no async, no API, no dispatch, no side effects, no business decisions in setters).\n* [ ] Stores follow the region order and use `makeAutoObservable(this, {}, { autoBind: true })`.\n* [ ] Components reading stores are `observer`.\n* [ ] Errors are handled in Handles (state or `notification.show`).\n* [ ] Actions declared via module augmentation.\n* [ ] Dispatch uses the `actions` proxy.\n* [ ] Handles dispose every registration on unmount.\n",{"name":5,"description":7},"main","6f1867f215cf86d20099b6dfb1164c79abfb87ce","lab-10\u002F.codex\u002Fskills\u002Fcommand-bus-architecture",0,"https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab","https:\u002F\u002Fgithub.com\u002Fmaurodesouza","Software Engineer","2026-10-28 02:01:00",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add maurodesouza\u002Fai-kanban-app-lab --skill command-bus-architecture",{"tool":58,"command":59},"bunx","bunx skills add maurodesouza\u002Fai-kanban-app-lab --skill command-bus-architecture",{"tool":61,"command":62},"pnpm","pnpm dlx skills add maurodesouza\u002Fai-kanban-app-lab --skill command-bus-architecture","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Fcommand-bus-architecture\u002FSKILL.md",true,[],[67,92,109,131,142,153],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":73,"publishedAt":39},"01M6P519M13JTBZDK3ZJP48P2C","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.","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Futils-implementation\u002FSKILL.md",[],[74,75,76,77,78,79,80,81,82,83,84,85,86,34,87,88,89,90,91],"utils implementation","implementation","utils","parsing","for","object","storage","ids","clear","math","write","filtering","with","organize","domain","mapping","formatting","as",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":103,"publishedAt":39},"01M6P516BP8GPRJHPGVFWRF5T8","test-writer","Write tests for the current implementation","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Ftest-writer\u002FSKILL.md",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[104,105,106,107,84,75,108,78],"test","test writer","writer","write tests","tests",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":39},"01M6P50M0Z2AQH32ZTV90D5V32","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).","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Ftech-lead\u002FSKILL.md",[],[116,117,118,20,119,120,121,19,31,122,123,124,125,126,21,127,34,128,129,130],"tech","tech lead","ready","implement","github","EPIC","issues","ui","start","analyze","Rules","implementer","goal","stop","project",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":39},"01M6P50GND99S9QQY6KWPP6NW9","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.","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Ftech-lead-publish\u002FSKILL.md",[],[138,117,116,139,120,122,37,140,121,141],"tech lead publish","publish","dependency","information",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":39},"01M6P50D4P2SQSYZM7TZMHZA0J","setup-command-system","Install the Command System architecture in the project","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Fsetup-command-system\u002FSKILL.md",[],[149,21,150,151,19,152,130],"setup command system","system","setup","install",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":39},"01M6P50A032630X9JDDZYJMNV3","reviewer","Review code changes and provide feedback","https:\u002F\u002Fgithub.com\u002Fmaurodesouza\u002Fai-kanban-app-lab\u002Fblob\u002Fmain\u002Flab-10\u002F.codex\u002Fskills\u002Freviewer\u002FSKILL.md",[],[155,36,160,161,162,163],"review code","feedback","changes","review"]