commit
Create git commits with user approval and no Claude attribution
Check for frontend architecture pattern violations
$ npx -y skills add dcouple/Pane --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
/architecture-frontendContext preview
What this command does when you run it.
Check for frontend architecture pattern violations
allowed-tools: Bash(git diff:*), Bash(git log:*), Bash(git show:*), Bash(git rev-parse:*), Bash(git branch:*), Read, Grep, Glob, TodoWrite description: Check for frontend architecture pattern violations
You are reviewing code changes for violations of **frontend architecture patterns**.
Pages should be JSX composition only. All business logic, state management, and event handlers live in orchestration hooks (e.g., `usePageName`).
**Shared code (2+ features) goes in `src/components/`, `src/hooks/`, etc.**
Hooks return data and functions only. Components render JSX.
# Get current branch git rev-parse --abbrev-ref HEAD # Get changed files (frontend only) git diff main...HEAD --name-only | grep "apps/webapp" # Get full diff for frontend git diff main...HEAD -- "apps/webapp/"
Read the frontend patterns:
For each page file (`page.tsx`) changed:
**Check for thin composition:**
// CORRECT - Thin page
'use client';
export default function FeedPage() {
const { items, isLoading, handleRefresh } = useFeedPage();
if (isLoading) return <LoadingSpinner />;
return (
<PageLayout>
<FeedList items={items} onRefresh={handleRefresh} />
</PageLayout>
);
}
// WRONG - Fat page with logic
'use client';
export default function FeedPage() {
const [items, setItems] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch('/api/feed')
.then(res => res.json())
.then(data => {
setItems(data);
setIsLoading(false);
});
}, []);
const handleRefresh = async () => {
// 20 lines of logic...
};
return <div>...</div>;
}**Check for 'use client' directive:**
**Study exemplar:** `apps/webapp/src/app/(protected)/workspaces/[workspaceId]/feed/page.tsx`
For orchestration hooks (`usePage.ts`, `useFeature.ts`):
**Check for proper structure:**
// CORRECT
export function useFeedPage() {
// 1. Data hooks
const { data: items, isLoading } = useFeed();
// 2. State
const [filter, setFilter] = useState('all');
// 3. Mutations
const { mutate: refreshFeed } = useRefreshFeed();
// 4. Handlers
const handleRefresh = useCallback(() => {
refreshFeed();
}, [refreshFeed]);
// 5. Return object (NEVER JSX)
return {
items,
isLoading,
filter,
setFilter,
handleRefresh,
};
}
// WRONG - Returns JSX
export function useFeedPage() {
// ...
return <div>This is wrong</div>;
}**Study exemplar:** `apps/webapp/src/app/(protected)/workspaces/[workspaceId]/archive/useArchivePage.ts`
**Check file locations:**
app/workspaces/[id]/feed/
page.tsx
_components/ # Local to feed page
FeedList.tsx
FeedItem.tsx
_hooks/ # Local to feed page
useFeedPage.ts
src/components/ # Shared across features
Button.tsx
Modal.tsx
src/hooks/ # Shared across features
useFeed.ts**Flag violations:**
**Check query keys:**
// CORRECT - All dependencies in key
const { data } = useQuery({
queryKey: ['feed', workspaceId, filter],
queryFn: () => fetchFeed(workspaceId, filter),
});
// WRONG - Missing dependency
const { data } = useQuery({
queryKey: ['feed'],
queryFn: () => fetchFeed(workspaceId, filter),
});**Check mutation invalidation:**
// CORRECT - Invalidates related queries
const { mutate } = useMutation({
mutationFn: createItem,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['feed'] });
},
});
// WRONG - No invalidation
const { mutate } = useMutation({
mutationFn: createItem,
});**Check conditional queries:**
// CORRECT - Use enabled option
const { data } = useQuery({
queryKey: ['item', itemId],
queryFn: () => fetchItem(itemId),
enabled: !!itemId,
});
// WRONG - Conditional hook call
if (itemId) {
const { data } = useQuery(...);
}**Check that hooks never return JSX:**
// CORRECT
export function useModal() {
const [isOpen, setIsOpen] = useState(false);
return { isOpen, open: () => setIsOpen(true), close: () => setIsOpen(false) };
}
// WRONG
export function useModal() {
const [isOpen, setIsOpen] = useState(false);
return isOpen ? <Modal /> : null; // Never do this
}# Frontend Architecture Report
**Branch:** {branch}
**Status:** {PASS | WARN | FAIL}
## Summary
{One sentence assessment of frontend architecture compliance}
## Patterns Checked
- [x] Thin pages (JSX only)
- [x] Orchestration hooks
- [x] Underscore-prefix locality
- [x] TanStack Query patterns
- [x] Hooks return dRepo: dcouple/Pane
Create git commits with user approval and no Claude attribution
You are tasked with creating detailed implementation plans through an interactive, iterative process. You should be skeptical, thorough, and work…
Generate comprehensive PR descriptions following repository templates
You are tasked with implementing an approved technical plan from `thoughts/shared/plans/`. These plans contain phases with specific changes and success…
Iterate on existing implementation plans with thorough research and updates
You are tasked with conducting comprehensive research across the codebase to answer user questions. You will spawn one or more parallel sub-agents to perform…