rex-claude 1.1.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/guards/completion-guard.sh +40 -0
- package/dist/guards/dangerous-cmd-guard.sh +50 -0
- package/dist/guards/scope-guard.sh +16 -0
- package/dist/guards/session-summary.sh +42 -0
- package/dist/guards/test-protect-guard.sh +15 -0
- package/dist/guards/ui-checklist-guard.sh +44 -0
- package/dist/index.js +454 -0
- package/dist/init-YMRG5ZXU.js +248 -0
- package/dist/optimize-NE47FMOP.js +111 -0
- package/package.json +26 -22
- package/README.md +0 -163
- package/activity/activity.jsonl +0 -443
- package/activity/config.lua +0 -3
- package/activity/init.lua +0 -49
- package/dist/cli.js +0 -504
- package/dotfiles/CLAUDE.md +0 -136
- package/dotfiles/commands/clean.md +0 -8
- package/dotfiles/commands/doc.md +0 -8
- package/dotfiles/commands/review.md +0 -15
- package/dotfiles/commands/scaffold.md +0 -11
- package/dotfiles/commands/test.md +0 -11
- package/dotfiles/docs/cloudflare.md +0 -62
- package/dotfiles/docs/nextjs.md +0 -79
- package/dotfiles/docs/react.md +0 -63
- package/dotfiles/docs/tailwind.md +0 -45
- package/dotfiles/docs/telegram-bot.md +0 -55
- package/dotfiles/rules/api-design.md +0 -63
- package/dotfiles/rules/defensive-engineering.md +0 -42
- package/dotfiles/rules/docs-first.md +0 -47
- package/dotfiles/rules/frontend.md +0 -41
- package/dotfiles/rules/git-workflow.md +0 -57
- package/dotfiles/rules/never-assume.md +0 -39
- package/dotfiles/rules/security.md +0 -46
- package/dotfiles/rules/testing.md +0 -33
- package/dotfiles/settings.json +0 -80
- package/dotfiles/skills/build-validate/SKILL.md +0 -16
- package/dotfiles/skills/code-review/SKILL.md +0 -18
- package/dotfiles/skills/context-loader/SKILL.md +0 -25
- package/dotfiles/skills/debug-assist/SKILL.md +0 -26
- package/dotfiles/skills/deploy-checklist/SKILL.md +0 -54
- package/dotfiles/skills/dstudio-design-system/SKILL.md +0 -120
- package/dotfiles/skills/figma-workflow/SKILL.md +0 -23
- package/dotfiles/skills/fix-issue/SKILL.md +0 -43
- package/dotfiles/skills/one-shot/SKILL.md +0 -18
- package/dotfiles/skills/pr-review-loop/SKILL.md +0 -41
- package/dotfiles/skills/project-init/SKILL.md +0 -45
- package/dotfiles/skills/research/SKILL.md +0 -17
- package/dotfiles/skills/spec-interview/SKILL.md +0 -20
- package/dotfiles/skills/token-guard/SKILL.md +0 -26
- package/dotfiles/templates/CLAUDE.md.template +0 -39
- package/memory/package.json +0 -24
- package/memory/src/embed.ts +0 -23
- package/memory/src/ingest.ts +0 -257
- package/memory/src/search.ts +0 -32
- package/memory/src/server.ts +0 -69
- package/memory/tsconfig.json +0 -14
- package/tmux/.tmux.conf +0 -73
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Run the project's test suite and analyze results.
|
|
2
|
-
|
|
3
|
-
Steps:
|
|
4
|
-
1. Detect test framework (look for vitest.config, jest.config, playwright.config)
|
|
5
|
-
2. Run the appropriate test command
|
|
6
|
-
3. If tests fail:
|
|
7
|
-
- Analyze each failure
|
|
8
|
-
- Identify root cause
|
|
9
|
-
- Suggest fixes (NEVER modify tests to make them pass — fix the code)
|
|
10
|
-
4. Report: total tests, passed, failed, skipped
|
|
11
|
-
5. If no test suite exists, report that and suggest setting one up
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Cloudflare Workers — Doc Cache Local
|
|
2
|
-
|
|
3
|
-
> Dernière mise à jour : 2026-03-03
|
|
4
|
-
|
|
5
|
-
## Workers Basics
|
|
6
|
-
|
|
7
|
-
### Limite clé : 50 subrequests/invocation
|
|
8
|
-
Pour les opérations en batch : chunking + self-invoke pattern.
|
|
9
|
-
|
|
10
|
-
```ts
|
|
11
|
-
export default {
|
|
12
|
-
async fetch(request: Request, env: Env): Promise<Response> {
|
|
13
|
-
const url = new URL(request.url);
|
|
14
|
-
// routing
|
|
15
|
-
if (url.pathname === '/api/items') return handleItems(request, env);
|
|
16
|
-
return new Response('Not found', { status: 404 });
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### D1 (SQLite)
|
|
22
|
-
```ts
|
|
23
|
-
const { results } = await env.DB.prepare('SELECT * FROM users WHERE id = ?')
|
|
24
|
-
.bind(userId)
|
|
25
|
-
.all();
|
|
26
|
-
// TOUJOURS requêtes paramétrées, jamais de concaténation
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### KV
|
|
30
|
-
```ts
|
|
31
|
-
await env.KV.put('key', JSON.stringify(value), { expirationTtl: 3600 });
|
|
32
|
-
const data = await env.KV.get('key', 'json');
|
|
33
|
-
// KV est eventually consistent — pas pour les données critiques temps réel
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Durable Objects
|
|
37
|
-
Pour state persistent + WebSocket — utilisé dans les bots Telegram.
|
|
38
|
-
|
|
39
|
-
## wrangler.toml
|
|
40
|
-
```toml
|
|
41
|
-
name = "my-worker"
|
|
42
|
-
main = "src/index.ts"
|
|
43
|
-
compatibility_date = "2025-01-01"
|
|
44
|
-
|
|
45
|
-
[[d1_databases]]
|
|
46
|
-
binding = "DB"
|
|
47
|
-
database_name = "my-db"
|
|
48
|
-
database_id = "xxx"
|
|
49
|
-
|
|
50
|
-
[[kv_namespaces]]
|
|
51
|
-
binding = "KV"
|
|
52
|
-
id = "xxx"
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Gotchas
|
|
56
|
-
|
|
57
|
-
1. **50 subrequests max** — inclut fetch(), D1, KV, tout appel réseau
|
|
58
|
-
2. **10ms CPU time** (free) / 30s (paid) — pas de boucles longues
|
|
59
|
-
3. **KV est eventually consistent** — délai de propagation ~60s
|
|
60
|
-
4. **D1 est en beta** — pas de transactions imbriquées
|
|
61
|
-
5. **CORS** : doit être géré manuellement dans le Worker
|
|
62
|
-
6. **`ctx.waitUntil()`** pour les tâches background après la réponse
|
package/dotfiles/docs/nextjs.md
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Next.js — Doc Cache Local
|
|
2
|
-
|
|
3
|
-
> Dernière mise à jour : 2026-03-03
|
|
4
|
-
> Version : Next.js 15.x / 16.x (App Router)
|
|
5
|
-
|
|
6
|
-
## App Router Essentials
|
|
7
|
-
|
|
8
|
-
### Route Files
|
|
9
|
-
- `page.tsx` — route UI
|
|
10
|
-
- `layout.tsx` — layout partagé (ne re-render pas à la navigation)
|
|
11
|
-
- `loading.tsx` — Suspense boundary automatique
|
|
12
|
-
- `error.tsx` — error boundary (`'use client'` obligatoire)
|
|
13
|
-
- `not-found.tsx` — 404 page
|
|
14
|
-
- `route.ts` — API route (GET, POST, PUT, DELETE)
|
|
15
|
-
|
|
16
|
-
### Server vs Client Components
|
|
17
|
-
- **Par défaut** : Server Component (pas de state, pas de hooks)
|
|
18
|
-
- `'use client'` en haut du fichier pour un Client Component
|
|
19
|
-
- Server Components peuvent importer Client Components, pas l'inverse
|
|
20
|
-
- Les props passées de Server → Client doivent être sérialisables
|
|
21
|
-
|
|
22
|
-
### Data Fetching (App Router)
|
|
23
|
-
```tsx
|
|
24
|
-
// Server Component — fetch direct, pas de useEffect
|
|
25
|
-
async function Page() {
|
|
26
|
-
const data = await fetch('https://api.example.com/data', {
|
|
27
|
-
cache: 'force-cache', // static (default)
|
|
28
|
-
// cache: 'no-store', // dynamic
|
|
29
|
-
// next: { revalidate: 60 } // ISR
|
|
30
|
-
});
|
|
31
|
-
return <div>{data}</div>;
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Server Actions
|
|
36
|
-
```tsx
|
|
37
|
-
'use server'
|
|
38
|
-
|
|
39
|
-
async function createItem(formData: FormData) {
|
|
40
|
-
const name = formData.get('name');
|
|
41
|
-
await db.insert(items).values({ name });
|
|
42
|
-
revalidatePath('/items');
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Gotchas / Pièges courants
|
|
47
|
-
|
|
48
|
-
1. **Hydration mismatch** : ne jamais utiliser `Date.now()`, `Math.random()`, ou `localStorage` dans le render initial — toujours dans `useEffect`
|
|
49
|
-
2. **`useSearchParams()`** : doit être wrappé dans `<Suspense>` sinon erreur en production
|
|
50
|
-
3. **Metadata** : export `metadata` ou `generateMetadata` uniquement dans `page.tsx` et `layout.tsx`
|
|
51
|
-
4. **Redirects dans Server Components** : utiliser `redirect()` de `next/navigation`, pas `router.push()`
|
|
52
|
-
5. **Route handlers** : `NextRequest` et `NextResponse` — pas `req`/`res` Express-style
|
|
53
|
-
6. **Middleware** : un seul fichier `middleware.ts` à la racine, matcher via config
|
|
54
|
-
|
|
55
|
-
## Patterns récurrents
|
|
56
|
-
|
|
57
|
-
### API Route avec validation
|
|
58
|
-
```tsx
|
|
59
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
60
|
-
|
|
61
|
-
export async function POST(request: NextRequest) {
|
|
62
|
-
try {
|
|
63
|
-
const body = await request.json();
|
|
64
|
-
// validate...
|
|
65
|
-
return NextResponse.json({ data: result }, { status: 201 });
|
|
66
|
-
} catch (error) {
|
|
67
|
-
return NextResponse.json({ error: 'Invalid request' }, { status: 400 });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Dynamic metadata
|
|
73
|
-
```tsx
|
|
74
|
-
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) {
|
|
75
|
-
const { id } = await params; // Next.js 15+ : params is async
|
|
76
|
-
const item = await getItem(id);
|
|
77
|
-
return { title: item.name };
|
|
78
|
-
}
|
|
79
|
-
```
|
package/dotfiles/docs/react.md
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# React 19 — Doc Cache Local
|
|
2
|
-
|
|
3
|
-
> Dernière mise à jour : 2026-03-03
|
|
4
|
-
|
|
5
|
-
## React 19 Nouveautés
|
|
6
|
-
|
|
7
|
-
### `use()` hook
|
|
8
|
-
```tsx
|
|
9
|
-
function Component({ dataPromise }: { dataPromise: Promise<Data> }) {
|
|
10
|
-
const data = use(dataPromise); // suspend until resolved
|
|
11
|
-
return <div>{data.name}</div>;
|
|
12
|
-
}
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Server Components
|
|
16
|
-
- Pas de state, pas de hooks (sauf `use()`)
|
|
17
|
-
- Accès direct aux données (DB, fichiers, APIs)
|
|
18
|
-
- Ne sont jamais envoyés au client (0 JS)
|
|
19
|
-
|
|
20
|
-
### Actions (form)
|
|
21
|
-
```tsx
|
|
22
|
-
function Form() {
|
|
23
|
-
const [state, formAction, isPending] = useActionState(async (prev, formData) => {
|
|
24
|
-
const result = await submitForm(formData);
|
|
25
|
-
return result;
|
|
26
|
-
}, null);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<form action={formAction}>
|
|
30
|
-
<input name="email" />
|
|
31
|
-
<button disabled={isPending}>Submit</button>
|
|
32
|
-
</form>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### `useOptimistic()`
|
|
38
|
-
```tsx
|
|
39
|
-
const [optimisticItems, addOptimistic] = useOptimistic(items, (state, newItem) => [...state, newItem]);
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Patterns récurrents
|
|
43
|
-
|
|
44
|
-
### Loading + Error + Empty states (OBLIGATOIRE)
|
|
45
|
-
```tsx
|
|
46
|
-
function ItemList() {
|
|
47
|
-
const { data, isLoading, error } = useQuery(...);
|
|
48
|
-
|
|
49
|
-
if (isLoading) return <Skeleton />;
|
|
50
|
-
if (error) return <ErrorMessage retry={refetch} />;
|
|
51
|
-
if (!data?.length) return <EmptyState message="Aucun élément" />;
|
|
52
|
-
|
|
53
|
-
return <ul>{data.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Gotchas
|
|
58
|
-
|
|
59
|
-
1. **StrictMode** double-render en dev — normal, pas un bug
|
|
60
|
-
2. **Key prop** : ne jamais utiliser l'index comme key si la liste peut être réordonnée
|
|
61
|
-
3. **Closure stale** dans useEffect — utiliser ref ou functional update
|
|
62
|
-
4. **Ref callback** : React 19 supporte le cleanup `return () => {}` dans les ref callbacks
|
|
63
|
-
5. **`forwardRef` deprecated** en React 19 — `ref` est maintenant une prop normale
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Tailwind CSS v4 — Doc Cache Local
|
|
2
|
-
|
|
3
|
-
> Dernière mise à jour : 2026-03-03
|
|
4
|
-
|
|
5
|
-
## v4 Breaking Changes
|
|
6
|
-
|
|
7
|
-
- Config via CSS (`@theme`), plus de `tailwind.config.js`
|
|
8
|
-
- Import : `@import "tailwindcss"` (plus de `@tailwind base/components/utilities`)
|
|
9
|
-
- Content detection automatique (plus besoin de `content: [...]`)
|
|
10
|
-
|
|
11
|
-
```css
|
|
12
|
-
@import "tailwindcss";
|
|
13
|
-
|
|
14
|
-
@theme {
|
|
15
|
-
--color-primary: #3b82f6;
|
|
16
|
-
--font-sans: "Inter", sans-serif;
|
|
17
|
-
}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Classes les plus utilisées
|
|
21
|
-
|
|
22
|
-
### Layout
|
|
23
|
-
- `flex` `flex-col` `items-center` `justify-between` `gap-4`
|
|
24
|
-
- `grid` `grid-cols-3` `col-span-2`
|
|
25
|
-
- `container` `mx-auto` `max-w-7xl`
|
|
26
|
-
|
|
27
|
-
### Spacing
|
|
28
|
-
- `p-4` `px-6` `py-2` `m-auto` `mt-8` `space-y-4`
|
|
29
|
-
|
|
30
|
-
### Typography
|
|
31
|
-
- `text-sm` `text-lg` `text-xl` `font-bold` `font-medium`
|
|
32
|
-
- `text-gray-600` `text-primary` `leading-relaxed`
|
|
33
|
-
|
|
34
|
-
### Responsive
|
|
35
|
-
- `sm:` (640px) `md:` (768px) `lg:` (1024px) `xl:` (1280px)
|
|
36
|
-
|
|
37
|
-
### Dark mode
|
|
38
|
-
- `dark:bg-gray-900` `dark:text-white`
|
|
39
|
-
|
|
40
|
-
## Gotchas
|
|
41
|
-
|
|
42
|
-
1. **v4 pas de config JS** — tout est en CSS maintenant
|
|
43
|
-
2. **`@apply`** fonctionne toujours mais déconseillé — préférer les classes directes
|
|
44
|
-
3. **Arbitrary values** : `w-[calc(100%-2rem)]` `text-[#1a1a1a]`
|
|
45
|
-
4. **Group/peer** : `group-hover:opacity-100` `peer-invalid:text-red-500`
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# Telegram Bot API — Doc Cache Local
|
|
2
|
-
|
|
3
|
-
> Dernière mise à jour : 2026-03-03
|
|
4
|
-
|
|
5
|
-
## Rate Limits CRITIQUES
|
|
6
|
-
|
|
7
|
-
- **30 messages/seconde** par bot (global)
|
|
8
|
-
- **1 message/seconde** par chat (recommandé)
|
|
9
|
-
- **20 messages/minute** par groupe
|
|
10
|
-
- Batch : toujours ajouter des délais entre les envois
|
|
11
|
-
|
|
12
|
-
## Webhook vs Polling
|
|
13
|
-
|
|
14
|
-
Workers → webhook obligatoire :
|
|
15
|
-
```ts
|
|
16
|
-
// wrangler.toml : pas de cron, c'est un webhook
|
|
17
|
-
// POST https://api.telegram.org/bot{TOKEN}/setWebhook?url=https://my-worker.workers.dev/webhook
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Mini Apps
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
// Ouvrir une mini app depuis un bouton
|
|
24
|
-
{
|
|
25
|
-
reply_markup: {
|
|
26
|
-
inline_keyboard: [[{
|
|
27
|
-
text: "Open App",
|
|
28
|
-
web_app: { url: "https://my-app.pages.dev" }
|
|
29
|
-
}]]
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Validation initData côté serveur
|
|
35
|
-
```ts
|
|
36
|
-
import { createHmac } from 'crypto';
|
|
37
|
-
|
|
38
|
-
function validateInitData(initData: string, botToken: string): boolean {
|
|
39
|
-
const params = new URLSearchParams(initData);
|
|
40
|
-
const hash = params.get('hash');
|
|
41
|
-
params.delete('hash');
|
|
42
|
-
const sorted = [...params.entries()].sort().map(([k,v]) => `${k}=${v}`).join('\n');
|
|
43
|
-
const secret = createHmac('sha256', 'WebAppData').update(botToken).digest();
|
|
44
|
-
const expected = createHmac('sha256', secret).update(sorted).digest('hex');
|
|
45
|
-
return hash === expected;
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Gotchas
|
|
50
|
-
|
|
51
|
-
1. **Message trop long** : max 4096 chars — splitter si besoin
|
|
52
|
-
2. **Markdown parse mode** : utiliser `parse_mode: 'HTML'` (plus fiable que MarkdownV2)
|
|
53
|
-
3. **Callback query** : toujours `answerCallbackQuery()` sinon le spinner tourne indéfiniment
|
|
54
|
-
4. **Fichiers** : max 50MB download, 20MB upload via bot API
|
|
55
|
-
5. **Fallback Telegraph** : toujours avoir une page telegra.ph de backup
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# API Design
|
|
2
|
-
|
|
3
|
-
## REST Conventions
|
|
4
|
-
|
|
5
|
-
- URLs en kebab-case, noms de ressources au pluriel : `/api/v1/users`, `/api/v1/order-items`
|
|
6
|
-
- Verbes HTTP sémantiques : GET (lecture), POST (création), PUT/PATCH (mise à jour), DELETE (suppression)
|
|
7
|
-
- Versioning via URL prefix : `/api/v1/`
|
|
8
|
-
|
|
9
|
-
## Response Envelope
|
|
10
|
-
|
|
11
|
-
Toute réponse API doit suivre cette structure :
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"data": { ... },
|
|
16
|
-
"meta": {
|
|
17
|
-
"total": 150,
|
|
18
|
-
"limit": 20,
|
|
19
|
-
"offset": 0
|
|
20
|
-
},
|
|
21
|
-
"error": null
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
En cas d'erreur :
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"data": null,
|
|
30
|
-
"meta": {},
|
|
31
|
-
"error": {
|
|
32
|
-
"code": "VALIDATION_ERROR",
|
|
33
|
-
"message": "Le champ email est requis."
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Pagination OBLIGATOIRE
|
|
39
|
-
|
|
40
|
-
Toute liste doit accepter `limit` + `offset` et retourner `total` dans `meta`. Ne jamais retourner une liste non bornée.
|
|
41
|
-
|
|
42
|
-
## Status Codes
|
|
43
|
-
|
|
44
|
-
| Code | Signification |
|
|
45
|
-
|------|---------------|
|
|
46
|
-
| 200 | Succès |
|
|
47
|
-
| 201 | Ressource créée |
|
|
48
|
-
| 400 | Requête invalide |
|
|
49
|
-
| 401 | Non authentifié |
|
|
50
|
-
| 403 | Accès interdit |
|
|
51
|
-
| 404 | Ressource introuvable |
|
|
52
|
-
| 422 | Erreur de validation |
|
|
53
|
-
| 500 | Erreur serveur interne |
|
|
54
|
-
|
|
55
|
-
## Rate Limiting Headers
|
|
56
|
-
|
|
57
|
-
Inclure dans les réponses quand applicable :
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
X-RateLimit-Limit: 100
|
|
61
|
-
X-RateLimit-Remaining: 42
|
|
62
|
-
X-RateLimit-Reset: 1735689600
|
|
63
|
-
```
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Defensive Engineering
|
|
2
|
-
|
|
3
|
-
CRITICAL — apply to EVERY feature. Before writing ANY code, think through the full lifecycle: "What happens when this scales? What breaks? What are the edge cases?"
|
|
4
|
-
|
|
5
|
-
## Scale & Pagination
|
|
6
|
-
|
|
7
|
-
- NEVER assume a small, fixed number of items. Every list/query MUST support `limit` + `offset` and return `total`.
|
|
8
|
-
- Frontend: paginate with "Load more" — never fetch unbounded data in one call.
|
|
9
|
-
- Display counts from backend `total`, not loaded array `.length`.
|
|
10
|
-
|
|
11
|
-
## Frontend ↔ Backend Sync
|
|
12
|
-
|
|
13
|
-
- When adding/changing a backend endpoint, ALWAYS verify the frontend calls match (URL, params, response shape).
|
|
14
|
-
- When changing a response shape, grep ALL frontend consumers — don't miss any caller.
|
|
15
|
-
- When adding a new route file, verify it maps to the correct URL path (e.g., `functions/api/admin/foo.ts` → `/api/admin/foo`).
|
|
16
|
-
- After rename/move of an endpoint, search for ALL old references (fetch calls, imports, tests).
|
|
17
|
-
|
|
18
|
-
## Rate Limits & Platform Limits
|
|
19
|
-
|
|
20
|
-
- Telegram: 30 msgs/sec — batch with delays, never fire-and-forget all at once.
|
|
21
|
-
- Cloudflare Workers: 50 subrequests/invocation — chunk-based processing with self-invoking chain for large operations.
|
|
22
|
-
- Any external API: assume it WILL rate-limit you. Build retry with backoff or chunking from day one.
|
|
23
|
-
|
|
24
|
-
## Error Handling & Fallbacks
|
|
25
|
-
|
|
26
|
-
- Every `fetch()` can fail: network error, timeout, 4xx, 5xx. Handle ALL cases, not just the happy path.
|
|
27
|
-
- Show user-friendly errors, not raw API responses. Never expose internal errors to end users.
|
|
28
|
-
- For background/async operations: always provide a status check mechanism (polling, webhook callback).
|
|
29
|
-
- When a feature flag is OFF, related UI must hide gracefully — no broken references, no empty sections.
|
|
30
|
-
|
|
31
|
-
## Telegram Mini App Projects — Mandatory Setup
|
|
32
|
-
|
|
33
|
-
- Every mini app project MUST have a Telegraph (telegra.ph) backup page with all client links/contact info.
|
|
34
|
-
- This serves as fallback if the bot or Cloudflare goes down (different infra = true redundancy).
|
|
35
|
-
|
|
36
|
-
## Think Before Implementing
|
|
37
|
-
|
|
38
|
-
- For every new feature, ask: "What if there are 10x more users/items/requests than today?"
|
|
39
|
-
- For every API call, ask: "What if this returns empty? null? error? takes 30 seconds?"
|
|
40
|
-
- For every state change, ask: "Who else reads this state? Will they break?"
|
|
41
|
-
- For every DB query, ask: "Does this need an index? Will it scan the whole table at scale?"
|
|
42
|
-
- For multi-project sync: when a fix applies to shared code, ALWAYS replicate to greenhouse-bot + frenchconnection-bot.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Documentation-First Rule
|
|
2
|
-
|
|
3
|
-
## Principe
|
|
4
|
-
|
|
5
|
-
AVANT de coder quoi que ce soit avec un framework/lib, TOUJOURS :
|
|
6
|
-
1. Vérifier si la doc est déjà cachée localement dans `~/.claude/docs/`
|
|
7
|
-
2. Si oui → la lire en priorité (pas de fetch réseau)
|
|
8
|
-
3. Si non → fetcher via Context7 ou SiteMCP, puis sauvegarder les points clés dans `~/.claude/docs/`
|
|
9
|
-
|
|
10
|
-
## Cache local de documentation
|
|
11
|
-
|
|
12
|
-
Dossier : `~/.claude/docs/`
|
|
13
|
-
|
|
14
|
-
Structure :
|
|
15
|
-
```
|
|
16
|
-
docs/
|
|
17
|
-
├── nextjs.md # Next.js patterns, API routes, App Router
|
|
18
|
-
├── react.md # React 19 patterns, hooks, server components
|
|
19
|
-
├── cloudflare.md # Workers, D1, KV, Pages
|
|
20
|
-
├── cakephp.md # CakePHP conventions, ORM, routing
|
|
21
|
-
├── ionic.md # Ionic/Angular patterns, Capacitor
|
|
22
|
-
├── flutter.md # Flutter widgets, state management
|
|
23
|
-
├── tailwind.md # Tailwind classes, config, plugins
|
|
24
|
-
├── drizzle.md # Drizzle ORM schema, queries, migrations
|
|
25
|
-
├── telegram-bot.md # Bot API, mini apps, webhooks
|
|
26
|
-
├── n8n.md # n8n nodes, workflows, webhooks
|
|
27
|
-
└── {lib}.md # Ajouté au fur et à mesure
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Quand documenter
|
|
31
|
-
|
|
32
|
-
Après chaque projet, si un pattern/API/gotcha a été découvert :
|
|
33
|
-
1. Ouvrir le fichier `~/.claude/docs/{framework}.md`
|
|
34
|
-
2. Ajouter le pattern sous la bonne section
|
|
35
|
-
3. Format : titre court + snippet de code + gotcha/piège éventuel
|
|
36
|
-
|
|
37
|
-
## Outils disponibles
|
|
38
|
-
|
|
39
|
-
- **Context7** (MCP) : `use context7` → docs versionnées de n'importe quelle lib npm/PyPI
|
|
40
|
-
- **SiteMCP** (MCP) : docs complètes de sites crawlés (Next.js, Cloudflare, etc.)
|
|
41
|
-
- **`~/.claude/docs/`** : cache Markdown local, lu en priorité, jamais expiré
|
|
42
|
-
|
|
43
|
-
## Règle d'or
|
|
44
|
-
|
|
45
|
-
Ne jamais coder "de mémoire" un framework qu'on n'a pas utilisé depuis > 2 semaines.
|
|
46
|
-
Toujours vérifier les docs, même pour les APIs qu'on pense connaître.
|
|
47
|
-
Les breaking changes entre versions sont la première cause de bugs silencieux.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Frontend Rules
|
|
2
|
-
|
|
3
|
-
## États obligatoires pour chaque composant qui fetch
|
|
4
|
-
|
|
5
|
-
TOUJOURS implémenter les trois états :
|
|
6
|
-
|
|
7
|
-
1. **Loading state** : spinner ou skeleton pendant le fetch
|
|
8
|
-
2. **Empty state** : message clair si 0 résultat (jamais un composant vide sans explication)
|
|
9
|
-
3. **Error state** : message d'erreur lisible, option de retry si pertinent
|
|
10
|
-
|
|
11
|
-
## SSR / Next.js
|
|
12
|
-
|
|
13
|
-
- JAMAIS lire `window`, `localStorage`, `sessionStorage` ou tout browser API pendant le render initial (serveur).
|
|
14
|
-
- Utiliser `useEffect` pour accéder aux browser APIs côté client uniquement.
|
|
15
|
-
- Le HTML généré côté serveur DOIT correspondre exactement au premier render client — sinon hydration mismatch.
|
|
16
|
-
|
|
17
|
-
Exemple correct :
|
|
18
|
-
```tsx
|
|
19
|
-
const [value, setValue] = useState<string | null>(null);
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
setValue(localStorage.getItem('key'));
|
|
23
|
-
}, []);
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Hydration
|
|
27
|
-
|
|
28
|
-
- Les données dynamiques (date, heure, valeurs aléatoires) doivent être initialisées après montage via `useEffect`, jamais directement dans le state initial.
|
|
29
|
-
- Tester explicitement les hydration warnings dans la console du navigateur.
|
|
30
|
-
|
|
31
|
-
## Formulaires
|
|
32
|
-
|
|
33
|
-
- Validation côté client ET côté serveur — toujours les deux.
|
|
34
|
-
- Ne jamais faire confiance aux données envoyées par le client côté serveur.
|
|
35
|
-
- Désactiver le bouton de soumission pendant le chargement pour éviter les doubles soumissions.
|
|
36
|
-
|
|
37
|
-
## Accessibilité
|
|
38
|
-
|
|
39
|
-
- Tous les `<input>` doivent avoir un `<label>` associé (via `for`/`htmlFor` ou `aria-label`).
|
|
40
|
-
- Utiliser les rôles ARIA quand le composant ne correspond pas à un élément HTML sémantique natif.
|
|
41
|
-
- Les images doivent avoir un attribut `alt` descriptif (ou `alt=""` si purement décoratif).
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Git Workflow
|
|
2
|
-
|
|
3
|
-
## Conventional Commits
|
|
4
|
-
|
|
5
|
-
Format : `type(scope): description courte`
|
|
6
|
-
|
|
7
|
-
| Type | Usage |
|
|
8
|
-
|------------|-------|
|
|
9
|
-
| `feat:` | Nouvelle fonctionnalité |
|
|
10
|
-
| `fix:` | Correction de bug |
|
|
11
|
-
| `refactor:`| Refactoring sans changement de comportement |
|
|
12
|
-
| `chore:` | Maintenance, dépendances, config |
|
|
13
|
-
| `docs:` | Documentation uniquement |
|
|
14
|
-
| `test:` | Ajout ou modification de tests |
|
|
15
|
-
| `perf:` | Amélioration de performance |
|
|
16
|
-
|
|
17
|
-
Exemples :
|
|
18
|
-
```
|
|
19
|
-
feat(auth): add JWT refresh token rotation
|
|
20
|
-
fix(orders): correct total calculation on discounted items
|
|
21
|
-
chore: upgrade dependencies to latest minor versions
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Branches
|
|
25
|
-
|
|
26
|
-
- TOUJOURS créer une nouvelle branche sauf instruction contraire.
|
|
27
|
-
- Nommage kebab-case descriptif :
|
|
28
|
-
- `fix/auth-token-refresh`
|
|
29
|
-
- `feat/add-oauth-google`
|
|
30
|
-
- `refactor/orders-service-cleanup`
|
|
31
|
-
- Ne jamais commiter directement sur `main` ou `master`.
|
|
32
|
-
|
|
33
|
-
## Avant de commiter
|
|
34
|
-
|
|
35
|
-
1. Lancer le linter/formatter s'il existe
|
|
36
|
-
2. Vérifier qu'aucun secret ou fichier `.env` n'est inclus
|
|
37
|
-
3. Relire le diff (`git diff --staged`) avant de confirmer
|
|
38
|
-
|
|
39
|
-
## Pull Requests
|
|
40
|
-
|
|
41
|
-
- Titre court et clair (< 72 caractères)
|
|
42
|
-
- Description : contexte du changement + test plan
|
|
43
|
-
- Lier l'issue ou la tâche Monday associée si applicable
|
|
44
|
-
|
|
45
|
-
## PR Review Loop
|
|
46
|
-
|
|
47
|
-
1. Après création, récupérer les commentaires automatisés :
|
|
48
|
-
- `gh pr view <number> --comments`
|
|
49
|
-
- `gh api repos/{owner}/{repo}/pulls/{number}/comments`
|
|
50
|
-
2. Évaluer chaque commentaire : corriger ce qui est valide, ignorer ce qui ne l'est pas
|
|
51
|
-
3. Push des corrections, notifier l'utilisateur pour review du diff v1 → v2
|
|
52
|
-
|
|
53
|
-
## Règles absolues
|
|
54
|
-
|
|
55
|
-
- JAMAIS de `Co-Authored-By` dans les commits
|
|
56
|
-
- JAMAIS mentionner Claude, AI ou un assistant dans les messages de commit, PR ou issues
|
|
57
|
-
- JAMAIS `git push --force` sur main/master
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Never Assume
|
|
2
|
-
|
|
3
|
-
## Environnement & Outils
|
|
4
|
-
|
|
5
|
-
- JAMAIS assumer qu'un framework, lib ou commande est installé → vérifier d'abord (`which`, `ls node_modules`, `package.json`)
|
|
6
|
-
- JAMAIS assumer la version d'un outil → lire `package.json`, `pubspec.yaml`, `composer.json`, etc.
|
|
7
|
-
|
|
8
|
-
## Structure du projet
|
|
9
|
-
|
|
10
|
-
- JAMAIS assumer la structure d'un projet → lire le code existant avant de modifier quoi que ce soit
|
|
11
|
-
- JAMAIS créer un fichier sans avoir vérifié qu'un fichier similaire n'existe pas déjà
|
|
12
|
-
- JAMAIS assumer qu'un pattern utilisé ailleurs dans le projet est le bon — vérifier les conventions locales
|
|
13
|
-
|
|
14
|
-
## APIs & Données
|
|
15
|
-
|
|
16
|
-
- JAMAIS assumer qu'une API retourne un format spécifique → vérifier la doc ou le code
|
|
17
|
-
- JAMAIS assumer qu'une liste est non-vide → toujours gérer le cas `[]` ou `null`
|
|
18
|
-
- JAMAIS assumer qu'un champ est présent dans une réponse → accès défensif avec fallback
|
|
19
|
-
|
|
20
|
-
## TypeScript & Qualité
|
|
21
|
-
|
|
22
|
-
- JAMAIS utiliser `@ts-ignore` sans justification explicite dans un commentaire expliquant pourquoi
|
|
23
|
-
- JAMAIS utiliser `eslint-disable` sans justification explicite
|
|
24
|
-
- JAMAIS utiliser `any` comme type sans documenter pourquoi c'est inévitable
|
|
25
|
-
- Alternative : typer correctement, utiliser `unknown` + type guard si le type est incertain
|
|
26
|
-
|
|
27
|
-
## Comportement en cas d'ambiguïté
|
|
28
|
-
|
|
29
|
-
- TOUJOURS poser des questions en cas d'ambiguïté — accompagnement et précision > vitesse
|
|
30
|
-
- Si une instruction est floue, demander une clarification plutôt que d'interpréter et potentiellement mal comprendre
|
|
31
|
-
- Si deux approches semblent valides, présenter les options à l'utilisateur avant de choisir
|
|
32
|
-
|
|
33
|
-
## Principe "Mistakes become rules"
|
|
34
|
-
|
|
35
|
-
Chaque erreur récurrente identifiée en session de travail doit devenir une nouvelle règle dans `~/.claude/rules/`.
|
|
36
|
-
|
|
37
|
-
- Chaque interdit DOIT avoir une alternative : "Ne jamais X → utiliser Y à la place"
|
|
38
|
-
- Les règles doivent être actionnables, pas juste des interdictions vagues
|
|
39
|
-
- Exemple : "JAMAIS concaténer des strings SQL → TOUJOURS utiliser des requêtes paramétrées"
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Security Rules
|
|
2
|
-
|
|
3
|
-
## OWASP Top 10
|
|
4
|
-
|
|
5
|
-
Vérifier à chaque PR que le code ne présente aucune des vulnérabilités OWASP Top 10 :
|
|
6
|
-
injection, broken auth, exposition de données sensibles, XXE, broken access control, misconfiguration, XSS, insecure deserialization, composants vulnérables, logging insuffisant.
|
|
7
|
-
|
|
8
|
-
## Secrets & Credentials
|
|
9
|
-
|
|
10
|
-
- Secrets UNIQUEMENT dans `.env` / variables d'environnement — JAMAIS dans le code source.
|
|
11
|
-
- `.env` DOIT être dans `.gitignore`. Vérifier avant chaque commit.
|
|
12
|
-
- Ne jamais logger de tokens, mots de passe ou clés API, même en debug.
|
|
13
|
-
|
|
14
|
-
## SQL Injection
|
|
15
|
-
|
|
16
|
-
- Requêtes paramétrées UNIQUEMENT — jamais de concaténation de chaînes avec des données utilisateur.
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
// JAMAIS
|
|
20
|
-
db.query(`SELECT * FROM users WHERE id = ${userId}`);
|
|
21
|
-
|
|
22
|
-
// TOUJOURS
|
|
23
|
-
db.query('SELECT * FROM users WHERE id = ?', [userId]);
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## XSS (Cross-Site Scripting)
|
|
27
|
-
|
|
28
|
-
- Échapper tout input utilisateur affiché dans le DOM.
|
|
29
|
-
- Ne jamais utiliser `innerHTML` avec des données non sanitisées.
|
|
30
|
-
- Utiliser les mécanismes d'échappement natifs du framework (React échappe par défaut, sauf `dangerouslySetInnerHTML`).
|
|
31
|
-
|
|
32
|
-
## CORS
|
|
33
|
-
|
|
34
|
-
- Configurer explicitement les origines autorisées — jamais `*` en production.
|
|
35
|
-
- Limiter les méthodes et headers autorisés au strict nécessaire.
|
|
36
|
-
|
|
37
|
-
## Authentification & Tokens
|
|
38
|
-
|
|
39
|
-
- Tokens JWT/session avec expiration courte.
|
|
40
|
-
- Refresh tokens stockés en `httpOnly` cookies (pas en localStorage).
|
|
41
|
-
- Invalider les tokens côté serveur à la déconnexion.
|
|
42
|
-
- Rate limiter les endpoints d'authentification (login, reset password).
|
|
43
|
-
|
|
44
|
-
## Signalement
|
|
45
|
-
|
|
46
|
-
Si du code insécurisé est découvert en travaillant, le signaler immédiatement à l'utilisateur — ne pas ignorer.
|