From 7c14302b0612d5d2a5017d904a52191f17930359 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:36:30 -0300 Subject: [PATCH 01/21] feat(commands): add /rn-component scaffold command Introduces the /rn-component user-invocable command that generates a complete React Native component skeleton following the Layered Hook Architecture (View / ViewModel / Static Styles / Animated Styles / Services / Library). Includes SKILL.md, architecture reference doc, and 13 TypeScript/TSX template files with {{ComponentName}} placeholders. Co-Authored-By: Claude Sonnet 4.6 --- src/commands/rn-component/SKILL.md | 93 +++++++++++++++++++ .../rn-component/references/architecture.md | 45 +++++++++ .../references/templates/hooks/index.ts.tmpl | 2 + .../useComponentNameViewModel/index.ts.tmpl | 17 ++++ .../IUseComponentNameViewModelReturn.ts.tmpl | 4 + .../types/index.ts.tmpl | 1 + .../hooks/useReanimatedStyles/index.ts.tmpl | 15 +++ .../types/IUseReanimatedStylesProps.ts.tmpl | 1 + .../useReanimatedStyles/types/index.ts.tmpl | 1 + .../references/templates/index.tsx.tmpl | 13 +++ .../templates/library/index.ts.tmpl | 5 + .../templates/services/index.ts.tmpl | 5 + .../references/templates/styles.ts.tmpl | 15 +++ .../types/IComponentNameProps.ts.tmpl | 1 + .../references/templates/types/index.ts.tmpl | 1 + 15 files changed, 219 insertions(+) create mode 100644 src/commands/rn-component/SKILL.md create mode 100644 src/commands/rn-component/references/architecture.md create mode 100644 src/commands/rn-component/references/templates/hooks/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/index.tsx.tmpl create mode 100644 src/commands/rn-component/references/templates/library/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/services/index.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/styles.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/types/index.ts.tmpl diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md new file mode 100644 index 0000000..859f863 --- /dev/null +++ b/src/commands/rn-component/SKILL.md @@ -0,0 +1,93 @@ +--- +name: rn-component +description: Scaffolds a React Native component using the Layered Hook Architecture (View / ViewModel / Styles / Animated / Services / Library). Use ONLY when the user explicitly types /rn-component. +argument-hint: --name [--path ] +allowed-tools: Bash, Read, Write +model: haiku +--- + +## Pre-flight — Parse arguments + +Extract `--name` and `--path` values from `$ARGUMENTS`. + +- If `--name` is missing: stop and print `⚠️ Missing --name. Usage: /rn-component --name MyButton --path src/components` +- If `--name` is not valid PascalCase (`^[A-Z][A-Za-z0-9]*$`): stop and print `⚠️ Invalid component name. Must be PascalCase (e.g. MyButton).` +- If `--path` is missing: ask the user `Where should the component be created? Provide the output directory path:` and wait for their answer before continuing. +- If `--path` contains spaces: stop and print `⚠️ Path must not contain spaces. Please provide a single-token path.` + +## Derive variables + +- `ComponentName` = value of `--name` (PascalCase) +- `componentName` = `ComponentName` with first letter lowercased (camelCase) +- `outputDir` = `/` — resolve `--path` to an absolute path if relative (use `pwd` to resolve) + +## Collision check + +Run via Bash: +```bash +[ -d "" ] && [ "$(ls -A "")" ] && echo "NONEMPTY" || echo "OK" +``` + +If the result is `NONEMPTY`: stop and print `⚠️ already exists. Aborting to avoid overwrite.` + +## Architecture summary + +Read `references/architecture.md` (path relative to this SKILL.md file), then print a 3-line summary to the user: +- Layer overview (View / ViewModel / Styles / Animation / Services / Library) +- Type convention (I prefix for interfaces, barrel index.ts in every export folder) +- Barrel cycle rule (deep relative imports only, never ../..) + +## Create directory tree + +Run via Bash: +```bash +mkdir -p \ + /types \ + /hooks/useViewModel/types \ + /hooks/useReanimatedStyles/types \ + /services \ + /library +``` + +## Generate files + +For each template below: +1. Read the template file (path relative to this SKILL.md). +2. Replace every occurrence of `{{ComponentName}}` with the value of `ComponentName`. +3. Replace every occurrence of `{{componentName}}` with the value of `componentName`. +4. Write the result to the target path. + +| Template (relative to this file) | Target | +|-----------------------------------|--------| +| `references/templates/index.tsx.tmpl` | `/index.tsx` | +| `references/templates/styles.ts.tmpl` | `/styles.ts` | +| `references/templates/types/IComponentNameProps.ts.tmpl` | `/types/IProps.ts` | +| `references/templates/types/index.ts.tmpl` | `/types/index.ts` | +| `references/templates/hooks/index.ts.tmpl` | `/hooks/index.ts` | +| `references/templates/hooks/useComponentNameViewModel/index.ts.tmpl` | `/hooks/useViewModel/index.ts` | +| `references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl` | `/hooks/useViewModel/types/IUseViewModelReturn.ts` | +| `references/templates/hooks/useComponentNameViewModel/types/index.ts.tmpl` | `/hooks/useViewModel/types/index.ts` | +| `references/templates/hooks/useReanimatedStyles/index.ts.tmpl` | `/hooks/useReanimatedStyles/index.ts` | +| `references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl` | `/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts` | +| `references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl` | `/hooks/useReanimatedStyles/types/index.ts` | +| `references/templates/services/index.ts.tmpl` | `/services/index.ts` | +| `references/templates/library/index.ts.tmpl` | `/library/index.ts` | + +## Confirmation + +Run via Bash: +```bash +find -type f | sort +``` + +Print: +- `✓ Component scaffolded at ` +- `Note: ensure react-native-reanimated is installed in your project.` + +## Rules + +- Never run `git add`, never commit, never create a branch. Scaffolding only. +- Never overwrite existing files — the collision check blocks the whole run. +- Do not install dependencies. +- Do not reformat the user's existing code. +- Do not push. Do not open a PR. diff --git a/src/commands/rn-component/references/architecture.md b/src/commands/rn-component/references/architecture.md new file mode 100644 index 0000000..9494cda --- /dev/null +++ b/src/commands/rn-component/references/architecture.md @@ -0,0 +1,45 @@ +# Layered Hook Architecture + +This document defines the layering contract for React Native components scaffolded by `/rn-component`. + +## Layers + +### View (`index.tsx`) +- JSX only — no state, no logic, no side effects. +- Consumes exactly three hooks: `useStyles`, `useReanimatedStyles`, and `useViewModel`. +- Receives props typed as `IProps`. + +### ViewModel (`hooks/useViewModel/`) +- Single owner of all component logic. +- May use: `useState`, `useReducer`, `useMemo`, `useCallback`, `useEffect`, store subscriptions. +- Calls functions from `services/` and `library/` as needed. +- Returns `IUseViewModelReturn`. + +### Static Styles (`styles.ts`) +- Exports `useStyles(props: IProps)` — a hook that returns a `StyleSheet.create({})` result. +- Memoized with `useMemo`. +- No animated properties here. + +### Animation Styles (`hooks/useReanimatedStyles/`) +- All `react-native-reanimated` logic lives here. +- Receives `IUseReanimatedStylesProps` (never static styles). +- Never contains `StyleSheet.create` calls. + +### Services (`services/`) +- Plain async functions (API calls, AsyncStorage, etc.). +- No hooks allowed. +- Called from ViewModel only — never from the View. + +### Library (`library/`) +- Pure utility functions. +- No hooks, no side effects. +- May be called from ViewModel or from services. + +## Type conventions +- Interfaces use the `I` prefix: `IComponentNameProps`, `IUseComponentNameViewModelReturn`. +- Plain types (union, intersection, alias) have no prefix. +- Every folder that has public exports has a barrel `index.ts`. + +## Barrel cycle rule +Templates use deep relative imports only (e.g. `./types`, `../useReanimatedStyles/types`). +Never use `../..` shorthand — it creates import cycles between barrels. diff --git a/src/commands/rn-component/references/templates/hooks/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/index.ts.tmpl new file mode 100644 index 0000000..507270c --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/index.ts.tmpl @@ -0,0 +1,2 @@ +export * from './use{{ComponentName}}ViewModel'; +export * from './useReanimatedStyles'; diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl new file mode 100644 index 0000000..b04fce9 --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl @@ -0,0 +1,17 @@ +import { useCallback, useState } from 'react'; +import { I{{ComponentName}}Props } from '../../types'; +import { IUse{{ComponentName}}ViewModelReturn } from './types'; + +// All logic lives here — services and library calls are invoked from this hook. +export const use{{ComponentName}}ViewModel = ( + props: I{{ComponentName}}Props, +): IUse{{ComponentName}}ViewModelReturn => { + const [state, setState] = useState(null); + + const handleAction = useCallback(() => {}, []); + + return { + state, + handleAction, + }; +}; diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl new file mode 100644 index 0000000..06553aa --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl @@ -0,0 +1,4 @@ +export interface IUse{{ComponentName}}ViewModelReturn { + state: unknown; + handleAction: () => void; +} diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/index.ts.tmpl new file mode 100644 index 0000000..b9ad625 --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/index.ts.tmpl @@ -0,0 +1 @@ +export * from './IUse{{ComponentName}}ViewModelReturn'; diff --git a/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl new file mode 100644 index 0000000..025be13 --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl @@ -0,0 +1,15 @@ +import { useAnimatedStyle, useSharedValue } from 'react-native-reanimated'; +import { IUseReanimatedStylesProps } from './types'; + +// react-native-reanimated logic only — never static styles here. +export const useReanimatedStyles = (props: IUseReanimatedStylesProps) => { + const progress = useSharedValue(0); + + const animatedContainer = useAnimatedStyle(() => ({ + opacity: progress.value, + })); + + return { + animatedContainer, + }; +}; diff --git a/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl new file mode 100644 index 0000000..4dd3dbc --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl @@ -0,0 +1 @@ +export interface IUseReanimatedStylesProps {} diff --git a/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl new file mode 100644 index 0000000..05dddfd --- /dev/null +++ b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl @@ -0,0 +1 @@ +export * from './IUseReanimatedStylesProps'; diff --git a/src/commands/rn-component/references/templates/index.tsx.tmpl b/src/commands/rn-component/references/templates/index.tsx.tmpl new file mode 100644 index 0000000..0960e0f --- /dev/null +++ b/src/commands/rn-component/references/templates/index.tsx.tmpl @@ -0,0 +1,13 @@ +import React from 'react'; +import { View } from 'react-native'; +import { I{{ComponentName}}Props } from './types'; +import { useStyles } from './styles'; +import { use{{ComponentName}}ViewModel, useReanimatedStyles } from './hooks'; + +export const {{ComponentName}}: React.FC = (props) => { + const styles = useStyles(props); + const reanimatedStyles = useReanimatedStyles({}); + const {} = use{{ComponentName}}ViewModel(props); + + return ; +}; diff --git a/src/commands/rn-component/references/templates/library/index.ts.tmpl b/src/commands/rn-component/references/templates/library/index.ts.tmpl new file mode 100644 index 0000000..0e25762 --- /dev/null +++ b/src/commands/rn-component/references/templates/library/index.ts.tmpl @@ -0,0 +1,5 @@ +// Pure utilities. No hooks, no side effects. + +export function format{{ComponentName}}Label(input: string): string { + return input.trim(); +} diff --git a/src/commands/rn-component/references/templates/services/index.ts.tmpl b/src/commands/rn-component/references/templates/services/index.ts.tmpl new file mode 100644 index 0000000..8760cd9 --- /dev/null +++ b/src/commands/rn-component/references/templates/services/index.ts.tmpl @@ -0,0 +1,5 @@ +// Plain async functions (API, AsyncStorage, etc.). Call from ViewModel only. No hooks. + +export async function fetch{{ComponentName}}Data(): Promise { + return null; +} diff --git a/src/commands/rn-component/references/templates/styles.ts.tmpl b/src/commands/rn-component/references/templates/styles.ts.tmpl new file mode 100644 index 0000000..a215dc7 --- /dev/null +++ b/src/commands/rn-component/references/templates/styles.ts.tmpl @@ -0,0 +1,15 @@ +import { useMemo } from 'react'; +import { StyleSheet } from 'react-native'; +import { I{{ComponentName}}Props } from './types'; + +export const useStyles = (props: I{{ComponentName}}Props) => { + return useMemo( + () => + StyleSheet.create({ + container: { + flex: 1, + }, + }), + [], + ); +}; diff --git a/src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl b/src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl new file mode 100644 index 0000000..932a088 --- /dev/null +++ b/src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl @@ -0,0 +1 @@ +export interface I{{ComponentName}}Props {} diff --git a/src/commands/rn-component/references/templates/types/index.ts.tmpl b/src/commands/rn-component/references/templates/types/index.ts.tmpl new file mode 100644 index 0000000..ea9928b --- /dev/null +++ b/src/commands/rn-component/references/templates/types/index.ts.tmpl @@ -0,0 +1 @@ +export * from './I{{ComponentName}}Props'; From 23ee45d2898244e77e1baa76d75ec1cb8f2d131e Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:41:14 -0300 Subject: [PATCH 02/21] fix(rn-component): remove useMemo from useStyles template Architecture spec requires useStyles to return StyleSheet.create directly. useMemo was invented and not part of the spec. Co-Authored-By: Claude Sonnet 4.6 --- .../references/templates/styles.ts.tmpl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/commands/rn-component/references/templates/styles.ts.tmpl b/src/commands/rn-component/references/templates/styles.ts.tmpl index a215dc7..1f68d19 100644 --- a/src/commands/rn-component/references/templates/styles.ts.tmpl +++ b/src/commands/rn-component/references/templates/styles.ts.tmpl @@ -1,15 +1,10 @@ -import { useMemo } from 'react'; import { StyleSheet } from 'react-native'; import { I{{ComponentName}}Props } from './types'; export const useStyles = (props: I{{ComponentName}}Props) => { - return useMemo( - () => - StyleSheet.create({ - container: { - flex: 1, - }, - }), - [], - ); + return StyleSheet.create({ + container: { + flex: 1, + }, + }); }; From f82f234359b93e48d0827541ffd35a156849e8fd Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:41:23 -0300 Subject: [PATCH 03/21] fix(rn-component): remove invented stubs from ViewModel template Architecture spec requires only a placeholder comment and an empty return. Removes useState/useCallback stubs and fixes import to deep path to avoid barrel cycle. Co-Authored-By: Claude Sonnet 4.6 --- .../hooks/useComponentNameViewModel/index.ts.tmpl | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl index b04fce9..e057e68 100644 --- a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl @@ -1,17 +1,10 @@ -import { useCallback, useState } from 'react'; -import { I{{ComponentName}}Props } from '../../types'; +import { I{{ComponentName}}Props } from '../../types/I{{ComponentName}}Props'; import { IUse{{ComponentName}}ViewModelReturn } from './types'; -// All logic lives here — services and library calls are invoked from this hook. export const use{{ComponentName}}ViewModel = ( props: I{{ComponentName}}Props, ): IUse{{ComponentName}}ViewModelReturn => { - const [state, setState] = useState(null); + // state, effects, handlers - const handleAction = useCallback(() => {}, []); - - return { - state, - handleAction, - }; + return {}; }; From 7dea4e1114ce710674e2666dfbde3c3753814de7 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:41:34 -0300 Subject: [PATCH 04/21] fix(rn-component): remove invented fields from IUseViewModelReturn template Architecture spec leaves the return shape for the developer to define. The state and handleAction fields were invented and not part of the spec. Co-Authored-By: Claude Sonnet 4.6 --- .../types/IUseComponentNameViewModelReturn.ts.tmpl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl index 06553aa..1820f54 100644 --- a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/types/IUseComponentNameViewModelReturn.ts.tmpl @@ -1,4 +1 @@ -export interface IUse{{ComponentName}}ViewModelReturn { - state: unknown; - handleAction: () => void; -} +export interface IUse{{ComponentName}}ViewModelReturn {} From 8d1f369e36d372e95357b92f9819e3458f325dee Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:41:47 -0300 Subject: [PATCH 05/21] fix(rn-component): fix collision check bash bugs in SKILL.md Previous check used ls -A which allowed false negatives on empty dirs and || short-circuit masked permission errors. Replaced with a simple directory existence check. Co-Authored-By: Claude Sonnet 4.6 --- src/commands/rn-component/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md index 859f863..09ff461 100644 --- a/src/commands/rn-component/SKILL.md +++ b/src/commands/rn-component/SKILL.md @@ -25,10 +25,10 @@ Extract `--name` and `--path` values from `$ARGUMENTS`. Run via Bash: ```bash -[ -d "" ] && [ "$(ls -A "")" ] && echo "NONEMPTY" || echo "OK" +if [ -d "" ]; then echo "EXISTS"; else echo "OK"; fi ``` -If the result is `NONEMPTY`: stop and print `⚠️ already exists. Aborting to avoid overwrite.` +If the result is `EXISTS`: stop and print `⚠️ already exists. Aborting to avoid overwrite.` ## Architecture summary From f614285c882aa44241329b5479048f0a115c1c12 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:42:00 -0300 Subject: [PATCH 06/21] fix(rn-component): apply space check to interactively-supplied --path Space validation was only run when --path came from \$ARGUMENTS. Moving the check to after path resolution ensures it also covers paths provided interactively by the user. Co-Authored-By: Claude Sonnet 4.6 --- src/commands/rn-component/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md index 09ff461..84197ec 100644 --- a/src/commands/rn-component/SKILL.md +++ b/src/commands/rn-component/SKILL.md @@ -13,7 +13,7 @@ Extract `--name` and `--path` values from `$ARGUMENTS`. - If `--name` is missing: stop and print `⚠️ Missing --name. Usage: /rn-component --name MyButton --path src/components` - If `--name` is not valid PascalCase (`^[A-Z][A-Za-z0-9]*$`): stop and print `⚠️ Invalid component name. Must be PascalCase (e.g. MyButton).` - If `--path` is missing: ask the user `Where should the component be created? Provide the output directory path:` and wait for their answer before continuing. -- If `--path` contains spaces: stop and print `⚠️ Path must not contain spaces. Please provide a single-token path.` +- After `--path` is resolved (from arguments or from the user): if it contains spaces, stop and print `⚠️ Path must not contain spaces. Please provide a single-token path.` ## Derive variables From 6eb2f29d00152d69b46ed55f6d6f8e596111fae9 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:42:35 -0300 Subject: [PATCH 07/21] fix(rn-component): make services and library index barrels Co-Authored-By: Claude Sonnet 4.6 --- .../rn-component/references/templates/library/index.ts.tmpl | 6 +----- .../references/templates/services/index.ts.tmpl | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/commands/rn-component/references/templates/library/index.ts.tmpl b/src/commands/rn-component/references/templates/library/index.ts.tmpl index 0e25762..33e61d3 100644 --- a/src/commands/rn-component/references/templates/library/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/library/index.ts.tmpl @@ -1,5 +1 @@ -// Pure utilities. No hooks, no side effects. - -export function format{{ComponentName}}Label(input: string): string { - return input.trim(); -} +// export * from './format{{ComponentName}}Label'; diff --git a/src/commands/rn-component/references/templates/services/index.ts.tmpl b/src/commands/rn-component/references/templates/services/index.ts.tmpl index 8760cd9..e6f213b 100644 --- a/src/commands/rn-component/references/templates/services/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/services/index.ts.tmpl @@ -1,5 +1 @@ -// Plain async functions (API, AsyncStorage, etc.). Call from ViewModel only. No hooks. - -export async function fetch{{ComponentName}}Data(): Promise { - return null; -} +// export * from './fetch{{ComponentName}}Data'; From f7889ebd5942fbdcf4abc43bb5bb0a710bf2b49e Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:43:25 -0300 Subject: [PATCH 08/21] feat(rn-component): add example files to services and library Co-Authored-By: Claude Sonnet 4.6 --- src/commands/rn-component/SKILL.md | 2 ++ .../templates/library/format{{ComponentName}}Label.ts.tmpl | 3 +++ .../rn-component/references/templates/library/index.ts.tmpl | 2 +- .../templates/services/fetch{{ComponentName}}Data.ts.tmpl | 3 +++ .../rn-component/references/templates/services/index.ts.tmpl | 2 +- 5 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 src/commands/rn-component/references/templates/library/format{{ComponentName}}Label.ts.tmpl create mode 100644 src/commands/rn-component/references/templates/services/fetch{{ComponentName}}Data.ts.tmpl diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md index 84197ec..9025814 100644 --- a/src/commands/rn-component/SKILL.md +++ b/src/commands/rn-component/SKILL.md @@ -71,7 +71,9 @@ For each template below: | `references/templates/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts.tmpl` | `/hooks/useReanimatedStyles/types/IUseReanimatedStylesProps.ts` | | `references/templates/hooks/useReanimatedStyles/types/index.ts.tmpl` | `/hooks/useReanimatedStyles/types/index.ts` | | `references/templates/services/index.ts.tmpl` | `/services/index.ts` | +| `references/templates/services/fetch{{ComponentName}}Data.ts.tmpl` | `/services/fetchData.ts` | | `references/templates/library/index.ts.tmpl` | `/library/index.ts` | +| `references/templates/library/format{{ComponentName}}Label.ts.tmpl` | `/library/formatLabel.ts` | ## Confirmation diff --git a/src/commands/rn-component/references/templates/library/format{{ComponentName}}Label.ts.tmpl b/src/commands/rn-component/references/templates/library/format{{ComponentName}}Label.ts.tmpl new file mode 100644 index 0000000..5254c1d --- /dev/null +++ b/src/commands/rn-component/references/templates/library/format{{ComponentName}}Label.ts.tmpl @@ -0,0 +1,3 @@ +export function format{{ComponentName}}Label(input: string): string { + return input.trim(); +} diff --git a/src/commands/rn-component/references/templates/library/index.ts.tmpl b/src/commands/rn-component/references/templates/library/index.ts.tmpl index 33e61d3..c129dab 100644 --- a/src/commands/rn-component/references/templates/library/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/library/index.ts.tmpl @@ -1 +1 @@ -// export * from './format{{ComponentName}}Label'; +export * from './format{{ComponentName}}Label'; diff --git a/src/commands/rn-component/references/templates/services/fetch{{ComponentName}}Data.ts.tmpl b/src/commands/rn-component/references/templates/services/fetch{{ComponentName}}Data.ts.tmpl new file mode 100644 index 0000000..d739cb7 --- /dev/null +++ b/src/commands/rn-component/references/templates/services/fetch{{ComponentName}}Data.ts.tmpl @@ -0,0 +1,3 @@ +export async function fetch{{ComponentName}}Data(): Promise { + return null; +} diff --git a/src/commands/rn-component/references/templates/services/index.ts.tmpl b/src/commands/rn-component/references/templates/services/index.ts.tmpl index e6f213b..4736a88 100644 --- a/src/commands/rn-component/references/templates/services/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/services/index.ts.tmpl @@ -1 +1 @@ -// export * from './fetch{{ComponentName}}Data'; +export * from './fetch{{ComponentName}}Data'; From 9e09cd2070000a079a8c8a9de18cab9167382348 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:44:08 -0300 Subject: [PATCH 09/21] fix(rn-component): rename IComponentNameProps template to use {{ComponentName}} placeholder Co-Authored-By: Claude Sonnet 4.6 --- src/commands/rn-component/SKILL.md | 2 +- ...mponentNameProps.ts.tmpl => I{{ComponentName}}Props.ts.tmpl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/commands/rn-component/references/templates/types/{IComponentNameProps.ts.tmpl => I{{ComponentName}}Props.ts.tmpl} (100%) diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md index 9025814..9eadf39 100644 --- a/src/commands/rn-component/SKILL.md +++ b/src/commands/rn-component/SKILL.md @@ -61,7 +61,7 @@ For each template below: |-----------------------------------|--------| | `references/templates/index.tsx.tmpl` | `/index.tsx` | | `references/templates/styles.ts.tmpl` | `/styles.ts` | -| `references/templates/types/IComponentNameProps.ts.tmpl` | `/types/IProps.ts` | +| `references/templates/types/I{{ComponentName}}Props.ts.tmpl` | `/types/IProps.ts` | | `references/templates/types/index.ts.tmpl` | `/types/index.ts` | | `references/templates/hooks/index.ts.tmpl` | `/hooks/index.ts` | | `references/templates/hooks/useComponentNameViewModel/index.ts.tmpl` | `/hooks/useViewModel/index.ts` | diff --git a/src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl b/src/commands/rn-component/references/templates/types/I{{ComponentName}}Props.ts.tmpl similarity index 100% rename from src/commands/rn-component/references/templates/types/IComponentNameProps.ts.tmpl rename to src/commands/rn-component/references/templates/types/I{{ComponentName}}Props.ts.tmpl From 1f8c2cce4dc15201633d6fc8a3b3fb59abe8f909 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Fri, 24 Apr 2026 05:44:59 -0300 Subject: [PATCH 10/21] fix(rn-component): use import type for all interface imports Co-Authored-By: Claude Sonnet 4.6 --- .../templates/hooks/useComponentNameViewModel/index.ts.tmpl | 4 ++-- .../templates/hooks/useReanimatedStyles/index.ts.tmpl | 2 +- src/commands/rn-component/references/templates/index.tsx.tmpl | 2 +- src/commands/rn-component/references/templates/styles.ts.tmpl | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl index e057e68..6334f82 100644 --- a/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/hooks/useComponentNameViewModel/index.ts.tmpl @@ -1,5 +1,5 @@ -import { I{{ComponentName}}Props } from '../../types/I{{ComponentName}}Props'; -import { IUse{{ComponentName}}ViewModelReturn } from './types'; +import type { I{{ComponentName}}Props } from '../../types/I{{ComponentName}}Props'; +import type { IUse{{ComponentName}}ViewModelReturn } from './types'; export const use{{ComponentName}}ViewModel = ( props: I{{ComponentName}}Props, diff --git a/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl index 025be13..1bac7de 100644 --- a/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl +++ b/src/commands/rn-component/references/templates/hooks/useReanimatedStyles/index.ts.tmpl @@ -1,5 +1,5 @@ import { useAnimatedStyle, useSharedValue } from 'react-native-reanimated'; -import { IUseReanimatedStylesProps } from './types'; +import type { IUseReanimatedStylesProps } from './types'; // react-native-reanimated logic only — never static styles here. export const useReanimatedStyles = (props: IUseReanimatedStylesProps) => { diff --git a/src/commands/rn-component/references/templates/index.tsx.tmpl b/src/commands/rn-component/references/templates/index.tsx.tmpl index 0960e0f..2c85cb1 100644 --- a/src/commands/rn-component/references/templates/index.tsx.tmpl +++ b/src/commands/rn-component/references/templates/index.tsx.tmpl @@ -1,6 +1,6 @@ import React from 'react'; import { View } from 'react-native'; -import { I{{ComponentName}}Props } from './types'; +import type { I{{ComponentName}}Props } from './types'; import { useStyles } from './styles'; import { use{{ComponentName}}ViewModel, useReanimatedStyles } from './hooks'; diff --git a/src/commands/rn-component/references/templates/styles.ts.tmpl b/src/commands/rn-component/references/templates/styles.ts.tmpl index 1f68d19..a410817 100644 --- a/src/commands/rn-component/references/templates/styles.ts.tmpl +++ b/src/commands/rn-component/references/templates/styles.ts.tmpl @@ -1,5 +1,5 @@ import { StyleSheet } from 'react-native'; -import { I{{ComponentName}}Props } from './types'; +import type { I{{ComponentName}}Props } from './types'; export const useStyles = (props: I{{ComponentName}}Props) => { return StyleSheet.create({ From a67a0b6ca7575ed983f86058bdc3407dfac5bb16 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Sat, 25 Apr 2026 18:30:45 -0300 Subject: [PATCH 11/21] docs: add JSX conditional rendering style guide Adds src/rules/jsx-style.md with complete JSX styling conventions, focusing on conditional rendering patterns and guard operators. Updates CLAUDE.md to reference the new rule and adds JSX guidance to rn-component architecture reference. Co-Authored-By: Claude Haiku 4.5 --- CLAUDE.md | 1 + .../rn-component/references/architecture.md | 16 ++++++ src/rules/jsx-style.md | 49 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/rules/jsx-style.md diff --git a/CLAUDE.md b/CLAUDE.md index 835039e..50fdefc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,6 @@ @src/rules/skills-format.md @src/rules/git-workflow.md +@src/rules/jsx-style.md ## Using skills diff --git a/src/commands/rn-component/references/architecture.md b/src/commands/rn-component/references/architecture.md index 9494cda..986045c 100644 --- a/src/commands/rn-component/references/architecture.md +++ b/src/commands/rn-component/references/architecture.md @@ -43,3 +43,19 @@ This document defines the layering contract for React Native components scaffold ## Barrel cycle rule Templates use deep relative imports only (e.g. `./types`, `../useReanimatedStyles/types`). Never use `../..` shorthand — it creates import cycles between barrels. + +## JSX conditional rendering +Never wrap a JSX branch of a ternary in `()`. Use the line-break form: + +```tsx +{isRequired + ? + + : null +} +``` + +See `src/rules/jsx-style.md` for the full rule and rationale. diff --git a/src/rules/jsx-style.md b/src/rules/jsx-style.md new file mode 100644 index 0000000..69d90cc --- /dev/null +++ b/src/rules/jsx-style.md @@ -0,0 +1,49 @@ +# JSX style + +## Conditional rendering + +Never wrap a JSX subtree in parentheses as the branch of a ternary. Use the "line-break ternary" form with the `?`, JSX, and `: null` on their own lines. + +### ✅ Correct + +```tsx +{isRequired + ? + + : null +} +``` + +For simple inline branches (single `` / primitive), keeping everything on a single line is fine: + +```tsx +{title ? {title} : null} +``` + +### ❌ Wrong + +```tsx +{isRequired ? ( + +) : null} +``` + +**Why:** Wrapping JSX in `()` as a ternary branch hides the structure — the `?` and `: null` visually collide with the JSX, and diffs become noisier when props change. The line-break form keeps the three pieces (`condition`, `JSX branch`, `else branch`) on their own axes and scans top-to-bottom. + +**How to apply:** +- Any time you render JSX conditionally inside another JSX tree. +- Applies equally to `?:` with `null` and to `?:` with another element. +- When both branches are JSX, keep each on its own line with the `?` / `:` on their own lines too. +- Never introduce `(` `)` around a JSX branch purely for ternary grouping. + +## `&&` guard + +Prefer `{cond ? : null}` over `{cond && }` when `cond` can be a falsy-but-renderable value (`0`, `''`, `NaN`) — React Native will render a stray `0` as text. Use `&&` only when `cond` is strictly boolean. From cc7983414e8dd80b5905710f4c904af3bd2989b8 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Sat, 25 Apr 2026 18:30:47 -0300 Subject: [PATCH 12/21] docs: add branch naming conventions Documents branch naming standards for release, dev, and feature branches, including version prefix requirements. Co-Authored-By: Claude Haiku 4.5 --- src/rules/git-workflow.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rules/git-workflow.md b/src/rules/git-workflow.md index 1377a7a..0fe02d5 100644 --- a/src/rules/git-workflow.md +++ b/src/rules/git-workflow.md @@ -7,3 +7,9 @@ Always follow this order when working with changes: 3. `/pr` — open PR from the branch to main Never commit directly to `main` or `master`. If already on `main`, run `/branch` first before any commits. + +## Branch naming conventions + +- Release branches: `release/v{version}` — always include the `v` prefix (e.g. `release/v0.2.0`, `release/v1.0.0`). +- Dev branches: `dev/v{version}` (e.g. `dev/v1.0.0`). +- Feature branches: `feat/{description}` (e.g. `feat/atoms-components`). From 44480c05c38dc8d1c2641a3c25264f9ed9e5cced Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Sat, 25 Apr 2026 18:32:26 -0300 Subject: [PATCH 13/21] docs(git-workflow): remove dev branch convention Simplifies branch naming rules to focus on release and feature branches. Co-Authored-By: Claude Haiku 4.5 --- src/rules/git-workflow.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rules/git-workflow.md b/src/rules/git-workflow.md index 0fe02d5..86931c4 100644 --- a/src/rules/git-workflow.md +++ b/src/rules/git-workflow.md @@ -11,5 +11,4 @@ Never commit directly to `main` or `master`. If already on `main`, run `/branch` ## Branch naming conventions - Release branches: `release/v{version}` — always include the `v` prefix (e.g. `release/v0.2.0`, `release/v1.0.0`). -- Dev branches: `dev/v{version}` (e.g. `dev/v1.0.0`). - Feature branches: `feat/{description}` (e.g. `feat/atoms-components`). From 6f404013c2dfd82df3b669a70ccc240c6f747fd7 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Mon, 27 Apr 2026 01:58:47 -0300 Subject: [PATCH 14/21] ci(deploy): improve release workflow order and error handling Reorder merge and tag steps to tag the correct commit on main, add `|| true` to branch deletion to prevent failure if branch doesn't exist, and upgrade checkout action to v5. Co-Authored-By: Claude Haiku 4.5 --- .github/workflows/deploy.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index db4d960..a127bdc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -78,7 +78,7 @@ jobs: echo "TAG=v$VERSION" >> "$GITHUB_ENV" - name: Checkout PR branch - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ env.PR_BRANCH }} fetch-depth: 0 @@ -108,9 +108,16 @@ jobs: run: | git push origin HEAD:${{ env.PR_BRANCH }} - - name: Create git tag + - name: Merge PR + run: | + gh pr merge ${{ env.PR_NUMBER }} \ + --merge \ + --repo ${{ github.repository }} + + - name: Tag merge commit on main run: | - git tag "${{ env.TAG }}" + git fetch origin main + git tag "${{ env.TAG }}" origin/main git push origin "${{ env.TAG }}" - name: Create GitHub Release @@ -120,15 +127,9 @@ jobs: --generate-notes \ --repo ${{ github.repository }} - - name: Merge PR - run: | - gh pr merge ${{ env.PR_NUMBER }} \ - --merge \ - --repo ${{ github.repository }} - - name: Delete release branch run: | - git push origin --delete "${{ env.PR_BRANCH }}" + git push origin --delete "${{ env.PR_BRANCH }}" || true - name: Post success comment if: success() From 993f8e1bda4f86b053594b9c0082492b95044282 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Mon, 27 Apr 2026 01:58:49 -0300 Subject: [PATCH 15/21] docs(commit): broaden skill trigger description Update the commit skill description to reflect its wider applicability across different user phrasings and languages for saving changes to git. Co-Authored-By: Claude Haiku 4.5 --- src/skills/commit/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/skills/commit/SKILL.md b/src/skills/commit/SKILL.md index ee9e759..64f0521 100644 --- a/src/skills/commit/SKILL.md +++ b/src/skills/commit/SKILL.md @@ -1,6 +1,6 @@ --- name: commit -description: This skill should be used when the user asks to "commit", "create commits", "commit changes", or wants to commit staged/unstaged changes following the Conventional Commits standard. +description: This skill should be used whenever the user wants to save, record, or commit changes to git — regardless of the language or phrasing used. argument-hint: [scope opcional] allowed-tools: [Agent] user-invocable: false From d1aac4a61cd7e0fb686435554b4fe4d625f42d49 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 30 Apr 2026 18:49:02 -0300 Subject: [PATCH 16/21] docs(rules): extract conventional commits format Extract commit types, format, and rules from commit skill into reusable rule file for reference across skills and commands. Co-Authored-By: Claude Haiku 4.5 --- src/rules/conventional-commits.md | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/rules/conventional-commits.md diff --git a/src/rules/conventional-commits.md b/src/rules/conventional-commits.md new file mode 100644 index 0000000..4675238 --- /dev/null +++ b/src/rules/conventional-commits.md @@ -0,0 +1,43 @@ +# Conventional Commits + +## Commit types + +| Type | When to use | +|---|---| +| `feat` | New feature | +| `fix` | Bug fix | +| `docs` | Documentation only | +| `style` | Formatting, whitespace (no logic change) | +| `refactor` | Code restructuring without feature/fix | +| `perf` | Performance improvement | +| `test` | Adding or updating tests | +| `build` | Build system, dependencies | +| `ci` | CI/CD configuration | +| `chore` | Maintenance, tooling | +| `raw` | Raw data, config files | +| `cleanup` | Dead code removal, cleanup | +| `remove` | Removing features or files | + +## Commit format + +``` +(): + +[optional body if subject is not enough] + +Co-Authored-By: Claude Haiku 4.5 +``` + +- Subject: max 50 characters, imperative mood ("add", not "added") +- Scope: optional, keep it short (1 word max: `auth`, `ui`, `config`) +- Description: 2–4 words only — no full sentences +- Body: only when the subject alone is insufficient + +## Rules + +- Never mix unrelated changes in one commit +- Prefer smaller, focused commits +- If a file contains changes of different natures, split them and mention in the body +- Use `git diff HEAD -- ` to inspect specific changes before deciding grouping +- Never use `git add .` or `git add -A` — always stage specific files by name +- Never run `git push` — committing only, pushing is the user's responsibility From aa2ceccc608eb8c2787c56dbb639e60a78f16768 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 30 Apr 2026 18:49:04 -0300 Subject: [PATCH 17/21] refactor(commit): remove duplicate format documentation Remove duplicated commit types, format, and rules from commit skill. Add reference to src/rules/conventional-commits.md instead. Co-Authored-By: Claude Haiku 4.5 --- src/skills/commit/SKILL.md | 44 ++------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/src/skills/commit/SKILL.md b/src/skills/commit/SKILL.md index 64f0521..5680808 100644 --- a/src/skills/commit/SKILL.md +++ b/src/skills/commit/SKILL.md @@ -22,6 +22,8 @@ To get the model ID: look in your system context for the line "The exact model I Your job is to analyze the git changes and create conventional commits. +Read `src/rules/conventional-commits.md` and follow it strictly for commit types, format, and rules. + ## Pre-flight check 1. Run `git branch --show-current` to get the current branch. @@ -36,39 +38,6 @@ Your job is to analyze the git changes and create conventional commits. 4. For each group, determine the commit type and create the commit 5. Print each commit name as it is created -## Commit types - -| Type | When to use | -|---|---| -| `feat` | New feature | -| `fix` | Bug fix | -| `docs` | Documentation only | -| `style` | Formatting, whitespace (no logic change) | -| `refactor` | Code restructuring without feature/fix | -| `perf` | Performance improvement | -| `test` | Adding or updating tests | -| `build` | Build system, dependencies | -| `ci` | CI/CD configuration | -| `chore` | Maintenance, tooling | -| `raw` | Raw data, config files | -| `cleanup` | Dead code removal, cleanup | -| `remove` | Removing features or files | - -## Commit format - -``` -(): - -[optional body if subject is not enough] - -Co-Authored-By: Claude Haiku 4.5 -``` - -- Subject: max 50 characters, imperative mood ("add", not "added") -- Scope: optional, keep it short (1 word max: `auth`, `ui`, `config`) -- Description: 2–4 words only — no full sentences -- Body: only when the subject alone is insufficient - ## Creating each commit For each group of changes: @@ -87,13 +56,4 @@ EOF 3. Print to the user: `✓ feat(auth): add JWT token refresh` Commit names appear one below the other as commits are created. - -## Rules - -- Never mix unrelated changes in one commit -- Prefer smaller, focused commits -- If a file contains changes of different natures, split them and mention in the body -- Use `git diff HEAD -- ` to inspect specific changes before deciding grouping -- Never use `git add .` or `git add -A` — always stage specific files by name -- Never run `git push` — this command only commits, pushing is the user's responsibility ``` From c90a41586a48cce0adb476dff2909339c437a679 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 30 Apr 2026 18:49:09 -0300 Subject: [PATCH 18/21] refactor(feature): reference workflow and commit rules Remove inline /branch and /commit logic from feature skill. Add references to git-workflow.md and conventional-commits.md. Add user-invocable: true to frontmatter. Co-Authored-By: Claude Haiku 4.5 --- src/commands/feature/SKILL.md | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/commands/feature/SKILL.md b/src/commands/feature/SKILL.md index 60b76ae..585ebad 100644 --- a/src/commands/feature/SKILL.md +++ b/src/commands/feature/SKILL.md @@ -1,6 +1,7 @@ --- name: feature description: This skill should be used when the user asks to "build a feature", "implement a feature", "develop a feature", or wants to autonomously develop, review, and ship a complete feature following the PDCA cycle. +user-invocable: true argument-hint: allowed-tools: [Bash, Read, Glob, Grep, Agent] model: sonnet @@ -87,23 +88,13 @@ Your job is to implement a feature exactly as described in the plan below. ## Instructions -1. Follow the /branch command logic to create the branch (feat/, fix/, dev/) based on the feature type. +Read `src/rules/git-workflow.md` for branch naming rules. +Read `src/rules/conventional-commits.md` for commit types, format, and rules. + +1. Create the branch following the branch naming rules from `git-workflow.md`. 2. Implement each step from the plan sequentially. -3. After each logical implementation chunk, follow the /commit command logic to commit (Conventional Commits, imperative, max 72 chars). -4. Co-author line on every commit: Co-Authored-By: Claude Sonnet 4.6 -5. After all implementation is done, check if any test file was created or modified. If no test was touched, note it in your final report. - -## /branch logic -- feat/ — new feature -- fix/ — bug fix -- dev/ — project/umbrella branch -- release/ — release, always with vX.X.X -- Lowercase, kebab-case, 2–4 words - -## /commit logic -- Run git add (never git add . or git add -A) -- Commit with HEREDOC format including co-author -- Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, cleanup, remove +3. After each logical implementation chunk, commit following `conventional-commits.md`. Co-author line on every commit: Co-Authored-By: Claude Sonnet 4.6 +4. After all implementation is done, check if any test file was created or modified. If no test was touched, note it in your final report. Do not push. Do not open a PR. From d27e5e6d14cbfeaff2cc5385e280248cac535813 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 30 Apr 2026 18:49:11 -0300 Subject: [PATCH 19/21] refactor(commands): add user-invocable frontmatter Add user-invocable: true to frontmatter for land and rn-component commands. Clean up rn-component description to remove redundant instruction. Co-Authored-By: Claude Haiku 4.5 --- src/commands/land/SKILL.md | 1 + src/commands/rn-component/SKILL.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands/land/SKILL.md b/src/commands/land/SKILL.md index afcfdbc..4991153 100644 --- a/src/commands/land/SKILL.md +++ b/src/commands/land/SKILL.md @@ -1,6 +1,7 @@ --- name: land description: Use when the user asks to create a branch and commit, or create a branch + commit + PR together. Orchestrates /branch and /commit while sharing the git diff context to avoid redundant reads. After committing, if the user also asked for a PR, invoke /pr. +user-invocable: true argument-hint: [optional: branch name or description] allowed-tools: [Bash, Read, Agent] --- diff --git a/src/commands/rn-component/SKILL.md b/src/commands/rn-component/SKILL.md index 9eadf39..11a1c8d 100644 --- a/src/commands/rn-component/SKILL.md +++ b/src/commands/rn-component/SKILL.md @@ -1,6 +1,7 @@ --- name: rn-component -description: Scaffolds a React Native component using the Layered Hook Architecture (View / ViewModel / Styles / Animated / Services / Library). Use ONLY when the user explicitly types /rn-component. +description: Scaffolds a React Native component using the Layered Hook Architecture (View / ViewModel / Styles / Animated / Services / Library). +user-invocable: true argument-hint: --name [--path ] allowed-tools: Bash, Read, Write model: haiku From d0491467a9a6cf2ae861d3736ed66a7ac1baa731 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 30 Apr 2026 18:49:13 -0300 Subject: [PATCH 20/21] docs(rules): document user-invocable frontmatter requirement Add documentation that commands must include user-invocable: true in frontmatter. Co-Authored-By: Claude Haiku 4.5 --- src/rules/skills-format.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rules/skills-format.md b/src/rules/skills-format.md index a98af8e..373c9c2 100644 --- a/src/rules/skills-format.md +++ b/src/rules/skills-format.md @@ -2,12 +2,12 @@ ## User-invokable commands (`/name`) -Commands are invoked **only** when the user explicitly types `/name`. Claude must never auto-trigger a command based on context — that is exclusively for skills. Use `commands//SKILL.md`: +Commands are invoked **only** when the user explicitly types `/name`. Claude must never auto-trigger a command based on context — that is exclusively for skills. Always include `user-invocable: true` in frontmatter. Use `commands//SKILL.md`: ``` commands/ └── / - ├── SKILL.md ← required + ├── SKILL.md ← required (must have user-invocable: true) ├── references/ ← optional ├── examples/ ← optional └── scripts/ ← optional From dc15216aa8bbbc5784599edcbc614dad05b35551 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:56:18 +0000 Subject: [PATCH 21/21] chore(release): bump version to 0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a2ac293..da6f309 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@salve-software/ai-workers", - "version": "0.1.2", + "version": "0.2.0", "description": "Central package for AI configurations and Claude Code rules.", "scripts": { "postinstall": "bash scripts/setup.sh"