Skip to content

Commit 1be41c2

Browse files
committed
chore: add cross-tool AI config files (AGENTS.md, .cursorrules, copilot-instructions.md)
Add tool-agnostic AI coding assistant configurations so contributors using any AI tool (Cursor, GitHub Copilot, Codex, etc.) can automatically load project conventions. - AGENTS.md: comprehensive tool-neutral conventions - .cursorrules: Cursor AI compact rules - .github/copilot-instructions.md: GitHub Copilot instructions All content derived from CLAUDE.md to ensure consistency. [3/3] AI tool settings exposure series
1 parent e017f3d commit 1be41c2

3 files changed

Lines changed: 233 additions & 0 deletions

File tree

.cursorrules

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# react-simplikit Cursor Rules
2+
3+
## Project
4+
5+
React hooks/components library. Monorepo: `packages/core` + `packages/mobile`.
6+
7+
## Architecture
8+
9+
Unidirectional layers: `components → hooks → utils → _internal`
10+
Mobile depends on core. Core must NOT depend on mobile.
11+
12+
## Code Style
13+
14+
- `type` over `interface` for type aliases
15+
- Named functions in useEffect: `useEffect(function handleResize() { ... }, [])`
16+
- Named exports only, no default exports
17+
- No `any` — strict TypeScript
18+
- `.js` extensions in relative imports
19+
- Zero runtime dependencies
20+
21+
## SSR-Safe Pattern
22+
23+
```ts
24+
const [state, setState] = useState(FIXED_INITIAL_VALUE);
25+
useEffect(function syncBrowserState() {
26+
if (isServer()) return;
27+
setState(getBrowserAPI());
28+
}, []);
29+
```
30+
31+
## Hook Returns
32+
33+
- 1 value → direct return
34+
- 2 values → tuple `[state, action]`
35+
- 3+ values → object `{ a, b, c }`
36+
37+
## Testing
38+
39+
- 100% coverage (Vitest)
40+
- SSR tests required for browser API hooks (`.ssr.test.ts`)
41+
- Use `renderHookSSR.serverOnly()` for SSR tests
42+
43+
## File Structure
44+
45+
Each hook in own folder: `src/hooks/useHookName/`
46+
- `index.ts`, `useHookName.ts`, `useHookName.spec.ts`, `useHookName.ssr.test.ts`
47+
- Docs: `useHookName.md` + `ko/useHookName.md`
48+
49+
## JSDoc
50+
51+
Required tags: `@description`, `@param`, `@returns`, `@example`
52+
53+
## Commits
54+
55+
Format: `<type>(<scope>): <description>`
56+
Types: feat, fix, docs, chore, refactor, test

.github/copilot-instructions.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copilot Instructions for react-simplikit
2+
3+
## Quick Reference
4+
5+
- Monorepo: `packages/core` (react-simplikit) + `packages/mobile` (@react-simplikit/mobile)
6+
- Architecture: `components → hooks → utils → _internal` (unidirectional, no circular imports)
7+
- Mobile depends on core; core must NOT depend on mobile
8+
9+
## Code Style Rules
10+
11+
- Use `type` not `interface` for type aliases
12+
- Named functions in useEffect: `useEffect(function handleResize() { ... }, [])`
13+
- No default exports — named exports only
14+
- No `any` types — strict TypeScript
15+
- Include `.js` in relative imports for ESM
16+
17+
## SSR-Safe Pattern (CRITICAL)
18+
19+
All browser API access must use this pattern:
20+
21+
```ts
22+
const [state, setState] = useState(FIXED_INITIAL_VALUE);
23+
useEffect(function syncBrowserState() {
24+
if (isServer()) return;
25+
setState(getBrowserAPI());
26+
}, []);
27+
```
28+
29+
Never call browser APIs during state initialization.
30+
31+
## Hook Return Values
32+
33+
- 1 value → return directly: `useDebounce<T>(value, delay): T`
34+
- 2 values → tuple: `useToggle(init): [boolean, () => void]`
35+
- 3+ values → object: `usePagination(): { page, nextPage, prevPage }`
36+
37+
## Testing
38+
39+
- 100% coverage required (Vitest)
40+
- SSR test required for browser API hooks:
41+
```ts
42+
import { renderHookSSR } from '../utils/renderHookSSR';
43+
it('is safe on server side rendering', () => {
44+
const result = renderHookSSR.serverOnly(() => useHookName());
45+
expect(result.current).toBeDefined();
46+
});
47+
```
48+
49+
## JSDoc Template
50+
51+
Every public API requires:
52+
53+
```ts
54+
/**
55+
* @description Brief description of what it does
56+
* @param paramName - Parameter description
57+
* @returns What the hook/function returns
58+
* @example
59+
* ```ts
60+
* const value = useHookName(param);
61+
* ```
62+
*/
63+
```
64+
65+
## File Structure
66+
67+
```
68+
src/hooks/useHookName/
69+
├── index.ts # Re-export
70+
├── useHookName.ts # Implementation
71+
├── useHookName.spec.ts # Tests
72+
├── useHookName.ssr.test.ts # SSR tests
73+
├── useHookName.md # English docs
74+
└── ko/useHookName.md # Korean docs
75+
```

AGENTS.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# AGENTS.md
2+
3+
> Tool-agnostic project conventions for AI coding assistants.
4+
> For Claude Code-specific instructions, see [CLAUDE.md](./CLAUDE.md).
5+
6+
## Project Overview
7+
8+
React utility hooks/components library. Monorepo with two packages:
9+
- `react-simplikit` (`packages/core`) — Platform-independent React hooks & components
10+
- `@react-simplikit/mobile` (`packages/mobile`) — Mobile web utilities (viewport, keyboard, layout)
11+
12+
## Architecture
13+
14+
Layer dependency is **unidirectional** — no upward or circular imports:
15+
16+
```
17+
components → hooks → utils → _internal
18+
```
19+
20+
- Components may use hooks, utils, _internal
21+
- Hooks may use utils, _internal
22+
- Utils may use _internal only
23+
- Mobile may depend on core; core must NOT depend on mobile
24+
25+
## File Structure
26+
27+
Each hook/component/util lives in its own folder with co-located docs:
28+
29+
```
30+
src/hooks/useHookName/
31+
├── index.ts # Re-export
32+
├── useHookName.ts # Implementation
33+
├── useHookName.spec.ts # Tests (core) / useHookName.test.ts (mobile)
34+
├── useHookName.ssr.test.ts # SSR safety tests
35+
├── useHookName.md # English docs
36+
└── ko/
37+
└── useHookName.md # Korean docs
38+
```
39+
40+
## Coding Standards
41+
42+
- **`type` over `interface`** — Always use `type` for type aliases
43+
- **Named functions in useEffect**`useEffect(function handleResize() { ... }, [])` not arrow functions
44+
- **Strict boolean checks**`value !== undefined` not `if (value)`
45+
- **Import extensions** — Include `.js` in relative imports for ESM compliance
46+
- **Named exports only** — No default exports
47+
- **No `any` types** — Full TypeScript strict mode
48+
- **Zero runtime dependencies**
49+
50+
### SSR-Safe Pattern
51+
52+
All hooks/utils accessing browser APIs must be SSR-safe:
53+
54+
```ts
55+
const [state, setState] = useState(FIXED_INITIAL_VALUE);
56+
useEffect(function syncBrowserState() {
57+
if (isServer()) return;
58+
setState(getBrowserAPI());
59+
}, []);
60+
```
61+
62+
Never initialize state with browser API calls (causes hydration mismatch).
63+
64+
### Hook Return Value Convention
65+
66+
- **Single value**: `useDebounce<T>(value, delay): T`
67+
- **Tuple** (2 items): `useToggle(init): [boolean, () => void]`
68+
- **Object** (3+ items): `usePagination(): { page, nextPage, prevPage }`
69+
70+
## Testing
71+
72+
- **100% coverage mandatory** — Enforced by Vitest coverage threshold
73+
- **SSR tests required** — All hooks accessing browser APIs need `.ssr.test.ts`
74+
- **SSR test pattern**:
75+
```ts
76+
import { renderHookSSR } from '../utils/renderHookSSR';
77+
it('is safe on server side rendering', () => {
78+
const result = renderHookSSR.serverOnly(() => useHookName());
79+
expect(result.current).toBeDefined();
80+
});
81+
```
82+
83+
## Documentation
84+
85+
- **Bilingual**: English + Korean (co-located in hook folders)
86+
- **JSDoc required**: Every public API must have `@description` + `@example` + `@param` + `@returns`
87+
88+
## Commit Convention
89+
90+
Format: `<type>(<scope>): <description>`
91+
92+
Types: `feat`, `fix`, `docs`, `chore`, `refactor`, `test`
93+
Scope: `core`, `mobile`, or area name
94+
95+
## Commands
96+
97+
```bash
98+
yarn build # Build all packages (tsup)
99+
yarn test # Run tests (Vitest)
100+
yarn fix # Auto-fix lint + format
101+
yarn typecheck # Type check (tsc --noEmit)
102+
```

0 commit comments

Comments
 (0)