kaide 1.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/bin/kaide.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { promises as fs } from "fs";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const command = process.argv[2];
8
+
9
+ if (command !== "init") {
10
+ console.log("Usage: npx kaide init");
11
+ process.exit(1);
12
+ }
13
+
14
+ let createdCount = 0;
15
+ let skippedCount = 0;
16
+
17
+ async function copyDir(src, dest) {
18
+ const entries = await fs.readdir(src, { withFileTypes: true });
19
+ await fs.mkdir(dest, { recursive: true });
20
+
21
+ for (const entry of entries) {
22
+ const srcPath = path.join(src, entry.name);
23
+ const destPath = path.join(dest, entry.name);
24
+
25
+ if (entry.isDirectory()) {
26
+ await copyDir(srcPath, destPath);
27
+ continue;
28
+ }
29
+
30
+ try {
31
+ await fs.access(destPath);
32
+ skippedCount++;
33
+ } catch {
34
+ await fs.mkdir(path.dirname(destPath), { recursive: true });
35
+ await fs.copyFile(srcPath, destPath);
36
+ createdCount++;
37
+ }
38
+ }
39
+ }
40
+
41
+ async function main() {
42
+ const templateDir = path.resolve(__dirname, "../templates");
43
+ const targetDir = process.cwd();
44
+
45
+ try {
46
+ await fs.access(templateDir);
47
+ await copyDir(templateDir, targetDir);
48
+
49
+ console.log(`\n${createdCount} created • ${skippedCount} skipped`);
50
+ console.log("✅ Kaide is ready. Try: Ask AI to plan a new feature.");
51
+ } catch (err) {
52
+ console.error("CLI setup failed:", err.message);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ main();
package/package.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "kaide",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "kaide": "./bin/kaide.js"
7
+ }
8
+ }
@@ -0,0 +1,54 @@
1
+ ---
2
+ description: "USE WHEN: Applying core principles and enforcing global project constraints."
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Core Constitution
7
+
8
+ ## Constraints
9
+
10
+ - **INTENTIONAL_TODO Rule:** Usage is ONLY permitted for non-functional placeholders (e.g., temporary mock UI, future logging).
11
+ - **Business Integrity:** Forbidden to use `INTENTIONAL_TODO` for business logic, error handling, or API integrations.
12
+ - **Pseudo-code:** Forbidden. Provide working TypeScript/React code.
13
+ - **Reference:** Do not say "Usually done like this"; link to repo rules.
14
+ - **Validation:** Do not deliver without passing `pnpm check-types` and `pnpm lint`.
15
+ - **Search First:** Analyze existing patterns before coding.
16
+ - **Minimal Intervention:** Modify only necessary areas.
17
+ - **Source of Truth:** Reference the codebase. Correct it if erroneous.
18
+ - **Boy Scout:** Clean unused imports, `console.log`, and dead code.
19
+ - **Naming:** `kebab-case` for folders/non-component files; `PascalCase` for React components.
20
+ - **Exports:** Group exports with `index.ts`.
21
+ - **No Silent Failures:** Do not swallow errors. Manage `try/catch` blocks.
22
+ - **Secret Protection:** Do not log `.env` content.
23
+ - **Dependency:** Obtain approval for new packages.
24
+
25
+ ## Bans
26
+
27
+ - Comments (except JSDoc).
28
+ - Placeholders/incomplete code.
29
+ - `catch (e) {}` (Silent catch).
30
+ - Logging secrets.
31
+ - Out-of-scope refactoring.
32
+ - `// ...existing code` (Provide full blocks).
33
+ - Standard `TODO` or `FIXME` comments.
34
+ - Using `INTENTIONAL_TODO` to skip core logic implementation.
35
+
36
+ ## Correct Implementation
37
+
38
+ <example>
39
+ ```js
40
+ try {
41
+ process(data);
42
+ } catch (error) {
43
+ throw new ProcessingError({ cause: error });
44
+ }
45
+ ```
46
+ </example>
47
+
48
+ ## Incorrect Implementation
49
+
50
+ <incorrect-example>
51
+ ```js
52
+ try { process(data); } catch (e) {}
53
+ ```
54
+ </incorrect-example>
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: "USE WHEN: Defining HTTP requests, endpoints, and handling API responses."
3
+ globs: "src/lib/api.ts,src/features/**/api/*.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # API Layer
8
+
9
+ ## Constraints
10
+
11
+ - **Location:** Place all HTTP calls under `features/[feature]/api`.
12
+ - **Validation:** Use Zod for Input/Output validation.
13
+ - **Return Type:** Return typed data, not raw responses.
14
+ - **Error Handling:** Normalize API errors to `AppError` format.
15
+ - **Config:** Load `baseURL` from env. Use a single `axios` instance (`src/lib/api.ts`).
16
+ - **Interceptors:** Manage Auth, locale, and tenant logic in interceptors.
17
+ - **Naming:** `verb-entity.api.ts` (e.g., `get-users.api.ts`). Function: `getUsers`.
18
+ - **SSR Safety:** Use only whitelisted internal URLs or absolute paths for server-to-server calls to prevent SSRF.
19
+
20
+ ## Bans
21
+
22
+ - `fetch`/`axios` inside UI components.
23
+ - `axios.create` inside features.
24
+ - Cross-feature API imports.
25
+ - Using untyped responses.
26
+ - Hardcoded endpoint strings in queries.
27
+ - Throwing raw errors.
28
+ - Leaking internal error stack traces to the client or API responses.
29
+ - Constructing dynamic URLs using unsanitized user inputs.
30
+
31
+ ## Correct Implementation
32
+
33
+ <example>
34
+ ```ts
35
+ export const getUsers = async (): Promise<User[]> => {
36
+ const { data } = await api.get("/users");
37
+ return UserSchema.array().parse(data);
38
+ };
39
+ ```
40
+ </example>
41
+
42
+ ## Incorrect Implementation
43
+
44
+ <incorrect-example>
45
+ ```tsx
46
+ useEffect(() => { axios.get("/users"); }, []);
47
+ ```
48
+ </incorrect-example>
@@ -0,0 +1,45 @@
1
+ ---
2
+ description: "USE WHEN: Constructing forms, validating inputs, and managing form state with Zod schemas."
3
+ globs: "src/features/**/components/*Form*.tsx,src/features/**/schemas/*.ts"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Form Management
8
+
9
+ ## Constraints
10
+
11
+ - **Library:** Use `react-hook-form` + `@hookform/resolvers/zod`.
12
+ - **Schema:** Store schemas in `features/[feature]/schemas/`.
13
+ - **Defaults:** Define `defaultValues` fully using `z.infer` from the schema.
14
+ - **Performance:** Use `useWatch` or `Controller` instead of `watch`.
15
+ - **Submission:** Use `handleSubmit`. Prevent double clicks with `isSubmitting`.
16
+ - **Errors:** Map server errors using `setError`.
17
+
18
+ ## Bans
19
+
20
+ - Manually managing native `form` submit events.
21
+ - Using `watch()` at the root level.
22
+ - Synchronizing form state with `useEffect`.
23
+ - Defining schemas inside component files.
24
+ - Managing form inputs with `useState`.
25
+
26
+ ## Correct Implementation
27
+
28
+ <example>
29
+ ```tsx
30
+ const form = useForm<z.infer<typeof Schema>>({
31
+ resolver: zodResolver(Schema),
32
+ defaultValues: { email: "" }
33
+ });
34
+ const email = useWatch({ control: form.control, name: "email" });
35
+ ```
36
+ </example>
37
+
38
+ ## Incorrect Implementation
39
+
40
+ <incorrect-example>
41
+ ```tsx
42
+ const [email, setEmail] = useState("");
43
+ const values = form.watch(); // Root watch
44
+ ```
45
+ </incorrect-example>
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: "USE WHEN: Managing translation files (JSON), localization keys, or implementing multi-language logic."
3
+ globs: "src/messages/**/*.json,src/i18n/**/*.{ts,tsx},src/features/**"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Internationalization (i18n)
8
+
9
+ ## Constraints
10
+
11
+ - **Library Selection:** Delegate specific hook/method usage to the framework constitution (`nextjs.mdc` or `tanstack-start.mdc`).
12
+ - **Keys:** Use flat or max 3-level deep JSON structures. Use `camelCase` for keys.
13
+ - **SSOT:** All translation keys MUST be defined in `src/messages/`.
14
+ - **Type Safety:** Use the library's native type-generation features. Magic strings for keys are forbidden.
15
+ - **Namespacing:** Use namespaces for features (e.g., `auth.login`, `profile.settings`) to maintain modularity.
16
+
17
+ ## Bans
18
+
19
+ - Hardcoded strings in UI components.
20
+ - Dynamic key construction (e.g., `t("prefix." + variable)`).
21
+ - Reading locale via `window.location` or manual URL parsing.
22
+ - JSON hierarchy deeper than 3 levels.
23
+ - Async translation loading that causes layout shifts.
24
+
25
+ ## Correct Implementation
26
+
27
+ <example>
28
+ // Common Pattern (Usage details delegated to framework MDC)
29
+ const t = useTranslations("auth");
30
+ return <button>{t("loginButton")}</button>;
31
+ </example>
32
+
33
+ ## Incorrect Implementation
34
+
35
+ <incorrect-example>
36
+ // BAN: Hardcoded string
37
+ return <button>Login</button>;
38
+
39
+ // BAN: Dynamic key generation
40
+ const label = t("welcome_" + type);
41
+ </incorrect-example>
@@ -0,0 +1,91 @@
1
+ ---
2
+ description: Next.js 16 App Router Standards & Constraints
3
+ globs: src/app/**/{page,layout,loading,error,not-found}.tsx
4
+ alwaysApply: false
5
+ ---
6
+ # Next.js 16 App Router Constitution
7
+
8
+ ## Constraints
9
+
10
+ - **Server-First Architecture:** All components in `src/app` MUST be Server Components (RSC) by default.
11
+ - **Client Component Usage:** The `"use client"` directive is strictly limited to leaf-node components that require interactivity (hooks, events) or Browser APIs.
12
+ - **Feature Delegation:** `src/app` is strictly for routing/layout. All business logic, UI components, and domain hooks MUST reside in `src/features`.
13
+ - **Server Actions:** All mutations MUST use Server Actions defined in dedicated `actions.ts` files within `src/features`. Actions MUST call the API layer only; direct database access inside actions is forbidden.
14
+ - **i18n Implementation:** Use `next-intl` for translations. Follow the patterns defined in `i18n.mdc`.
15
+ - **Metadata:** SEO metadata MUST be defined using the Metadata API in `page.tsx` or `layout.tsx`.
16
+ - **Streaming:** Use `loading.tsx` for route-level async states. Use `<Suspense>` for granular feature-level hydration.
17
+ - **CSRF Protection:** Verify Origin/Referer headers in Server Actions. Use `action.bind` to lock sensitive IDs on the server-side.
18
+ - **Secret Isolation:** Use the `server-only` package in API and database files to prevent accidental leakage to the client.
19
+
20
+ ## Bans
21
+
22
+ - **Inline Server Actions:** Defining Server Actions inside components or pages is FORBIDDEN.
23
+ - **Client-Side Data Fetching in Effects:** Using `useEffect` for data fetching is FORBIDDEN. Use TanStack Query or RSC.
24
+ - **Logic in Route Files:** Implementing complex logic directly in `page.tsx` or `layout.tsx` is FORBIDDEN.
25
+ - **Manual Head Management:** Using `head.tsx` or manual `<meta>` tags is FORBIDDEN.
26
+ - **"use client" at Root:** Marking `page.tsx` or `layout.tsx` as `"use client"` is FORBIDDEN. Wrap interactive logic in feature components instead.
27
+ - **Raw Serialization:** Forbidden to pass raw database models or sensitive user data directly from RSC to Client Components.
28
+
29
+ ## Correct Implementation
30
+
31
+ <example>
32
+ // src/app/dashboard/page.tsx
33
+ import { DashboardFeature } from "@/features/dashboard";
34
+ import { getDashboardData } from "@/features/dashboard/api";
35
+ import { getTranslations } from "next-intl/server";
36
+
37
+ export async function generateMetadata() {
38
+ const t = await getTranslations("dashboard");
39
+ return { title: t("title") };
40
+ }
41
+
42
+ export default async function DashboardPage() {
43
+ const data = await getDashboardData();
44
+
45
+ return (
46
+ <main>
47
+ <DashboardFeature initialData={data} />
48
+ </main>
49
+ );
50
+ }
51
+ </example>
52
+
53
+ <example>
54
+ // src/features/auth/actions/login.ts
55
+ "use server";
56
+
57
+ import { loginSchema } from "../schemas/login-schema";
58
+ import { api } from "@/lib/api";
59
+
60
+ export async function loginAction(formData: FormData) {
61
+ const validated = loginSchema.parse(Object.fromEntries(formData));
62
+ return await api.post("/auth/login", validated);
63
+ }
64
+ </example>
65
+
66
+ ## Incorrect Implementation
67
+
68
+ <incorrect-example>
69
+ // BAN: "use client" on page level and useEffect fetching
70
+ "use client";
71
+
72
+ export default function Page() {
73
+ const [data, setData] = useState(null);
74
+ useEffect(() => {
75
+ fetch("/api/data").then(res => res.json()).then(setData);
76
+ }, []);
77
+
78
+ return <div>{data?.name}</div>;
79
+ }
80
+ </incorrect-example>
81
+
82
+ <incorrect-example>
83
+ // BAN: Inline server action
84
+ export default function Form() {
85
+ async function handle() {
86
+ "use server";
87
+ // database call
88
+ }
89
+ return <form action={handle}>...</form>;
90
+ }
91
+ </incorrect-example>
@@ -0,0 +1,61 @@
1
+ ---
2
+ description: "USE WHEN: Optimizing Core Web Vitals, managing assets, and ensuring high Lighthouse/A11y scores."
3
+ globs: "src/app/**/*.{ts,tsx},src/routes/**/*.{ts,tsx},src/components/**/*.{ts,tsx},src/features/**/components/**/*.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Performance & Accessibility (Lighthouse 95+)
8
+
9
+ ## Constraints
10
+
11
+ - **LCP Optimization:** Use `priority` attribute for the first visible `Image` (Next.js) or hero assets.
12
+ - **Image Standards:** Always use `next/image` or framework-specific optimized loaders. Define explicit `width` and `height` to prevent CLS.
13
+ - **Icon Strategy:** Use tree-shakable icons (e.g., `lucide-react`). Forbidden to import entire libraries.
14
+ - **Font Loading:** Use `swap` display strategy. Optimize via `next/font` or local self-hosting.
15
+ - **A11y SSOT:** All interactive elements MUST have `aria-label`, `role`, or associated `<label>`.
16
+ - **Contrast:** Maintain WCAG AA compliance (4.5:1 ratio).
17
+ - **Bundle Size:** Keep feature chunks <50kb. Use dynamic imports for heavy components (charts, editors).
18
+ - **Asset Links:** Ref: `ui-components.mdc` for Skeleton/CLS rules.
19
+
20
+ ## Bans
21
+
22
+ - **Layout Shift:** Forbidden to render content without reserved dimensions (use Skeletons).
23
+ - **Native Img:** Forbidden to use raw `<img>` tags.
24
+ - **Blocking JS:** Forbidden to use heavy 3rd party scripts in the main thread (use `next/script` or Web Workers).
25
+ - **A11y Gaps:** Forbidden to use `div` as a button without `tabIndex` and `onKeyDown`.
26
+ - **Alt Text:** Forbidden to leave `alt` attributes empty or generic (e.g., "image").
27
+
28
+ ## Correct Implementation
29
+
30
+ <example>
31
+ // Optimized LCP and A11y
32
+ import Image from "next/image";
33
+
34
+ export const Hero = () => (
35
+ <section>
36
+ <h1>{t("title")}</h1>
37
+ <Image
38
+ src="/hero.webp"
39
+ alt="Dashboard analytics overview"
40
+ width={1200}
41
+ height={600}
42
+ priority
43
+ />
44
+ <button aria-label="Start free trial" onClick={handleAction}>
45
+ {t("cta")}
46
+ </button>
47
+ </section>
48
+ );
49
+ </example>
50
+
51
+ ## Incorrect Implementation
52
+
53
+ <incorrect-example>
54
+ // BAN: Native img, no dimensions, no priority, no aria-label
55
+ const BadHero = () => (
56
+ <div>
57
+ <img src="/hero.png" />
58
+ <div onClick={handleAction}>Click here</div>
59
+ </div>
60
+ );
61
+ </incorrect-example>
@@ -0,0 +1,45 @@
1
+ ---
2
+ description: "USE WHEN: Designing React components, implementing hooks, and managing component lifecycles."
3
+ globs: "src/components/**/*.{ts,tsx},src/hooks/**/*.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # React Best Practices
8
+
9
+ ## Constraints
10
+
11
+ - **SRP:** Keep components small (max 150 lines).
12
+ - **Composition:** Use `children` or `slots` instead of prop drilling.
13
+ - **Naming:** Use `PascalCase` for components, `useCamelCase` for hooks.
14
+ - **Hooks:** Move business logic to custom hooks.
15
+ - **State:** Lift state to the nearest common ancestor.
16
+ - **Updates:** Use `setState(prev => ...)` for state updates.
17
+ - **Effects:** Use `useEffect` as a last resort. Prefer event handlers or `useMemo`.
18
+ - **Keys:** Use stable IDs for lists (index is forbidden).
19
+
20
+ ## Bans
21
+
22
+ - Prop drilling (>2 levels).
23
+ - Class components.
24
+ - Incomplete dependency arrays.
25
+ - Syncing props to state (use Derived state).
26
+ - Heavy computations during render.
27
+ - Data fetching inside components (violation of API rules).
28
+
29
+ ## Correct Implementation
30
+
31
+ <example>
32
+ ```tsx
33
+ const stableHandler = useEvent(handler);
34
+ useEffect(() => { stableHandler(data); }, [data]);
35
+ ```
36
+ </example>
37
+
38
+ ## Incorrect Implementation
39
+
40
+ <incorrect-example>
41
+ ```tsx
42
+ useEffect(() => { fetchData(); }, []); // Fetching forbidden
43
+ useEffect(() => { setVal(props.val); }, [props.val]); // Sync forbidden
44
+ ```
45
+ </incorrect-example>
@@ -0,0 +1,42 @@
1
+ ---
2
+ description: "USE WHEN: Managing global client state with Zustand and handling client-side state logic."
3
+ globs: "src/stores/**/*.ts,src/features/**/stores/**/*.ts"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # State Management
8
+
9
+ ## Constraints
10
+
11
+ - **Library:** Use `Zustand` for client state.
12
+ - **Scope:** Define Global state in `src/stores`, Feature state in `src/features/[feature]/stores`.
13
+ - **Selectors:** Always consume state via selectors (`useStore(s => s.val)`).
14
+ - **SSR:** Guarantee client-side rendering with `useHydrated`.
15
+ - **Persistence:** Configure `onRehydrateStorage` when using `persist` middleware.
16
+ - **Server State:** Use TanStack Query. Do not store server data in the global store.
17
+
18
+ ## Bans
19
+
20
+ - Passing store data via props.
21
+ - Storing high-frequency state (e.g., inputs) in the store.
22
+ - Executing side-effects (API calls) inside the store.
23
+ - Accessing `window`/`localStorage` during initialization.
24
+ - Returning the entire store without selectors.
25
+
26
+ ## Correct Implementation
27
+
28
+ <example>
29
+ ```ts
30
+ const user = useUserStore((s) => s.user);
31
+ const isHydrated = useHydrated();
32
+ ```
33
+ </example>
34
+
35
+ ## Incorrect Implementation
36
+
37
+ <incorrect-example>
38
+ ```ts
39
+ const { user } = useUserStore(); // Missing selector
40
+ const store = create(() => ({ data: localStorage.getItem("x") })); // SSR Error
41
+ ```
42
+ </incorrect-example>
@@ -0,0 +1,51 @@
1
+ ---
2
+ description: "USE WHEN: Managing server state, fetching data, and handling mutations with TanStack Query."
3
+ globs: "src/features/**/api/*.{ts,tsx},src/features/**/hooks/*.{ts,tsx},src/providers/query-provider.tsx"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # TanStack Query
8
+
9
+ ## Constraints
10
+
11
+ - **Structure:** Use Query Key Factory (`src/features/[feature]/api/query-keys.ts`).
12
+ - **Hooks:** Create custom hooks for every query/mutation.
13
+ - **Keys:** Use `as const`. Establish hierarchical structure (all -> lists -> details).
14
+ - **Signal:** Pass `AbortSignal` to the API function.
15
+ - **Invalidation:** Invalidate relevant keys in mutation `onSuccess`.
16
+ - **Pagination:** Include `page` and filters in the query key.
17
+
18
+ ## Bans
19
+
20
+ - `useQuery` inside components (Custom hooks are mandatory).
21
+ - Manual string query keys.
22
+ - Using API responses without validation.
23
+ - Ignoring Loading/Error states.
24
+
25
+ ## Correct Implementation
26
+
27
+ <example>
28
+ // features/skills/api/query-keys.ts
29
+ export const skillKeys = {
30
+ all: ['skills'] as const,
31
+ lists: () => [...skillKeys.all, 'list'] as const,
32
+ list: (filters: object) => [...skillKeys.lists(), { filters }] as const,
33
+ details: () => [...skillKeys.all, 'detail'] as const,
34
+ detail: (id: string) => [...skillKeys.details(), id] as const,
35
+ };
36
+
37
+ // features/skills/hooks/use-get-skills.ts
38
+ export const useGetSkills = (filters: object) =>
39
+ useQuery({
40
+ queryKey: skillKeys.list(filters),
41
+ queryFn: ({ signal }) => getSkills(filters, signal),
42
+ });
43
+ </example>
44
+
45
+ ## Incorrect Implementation
46
+
47
+ <incorrect-example>
48
+ ```tsx
49
+ useQuery({ queryKey: ["posts"], queryFn: () => axios.get("/posts") });
50
+ ```
51
+ </incorrect-example>
@@ -0,0 +1,85 @@
1
+ ---
2
+ description: TanStack Start Routing, Loaders, and Server Functions Standards
3
+ globs: src/routes/**/*.{ts,tsx}
4
+ alwaysApply: false
5
+ ---
6
+ # TanStack Start Constitution
7
+
8
+ ## Constraints
9
+
10
+ - **Route Definition:** Always use `createFileRoute`. Path MUST strictly match the file system location.
11
+ - **Component Scope:** Keep route files thin. Only orchestrate routing and data. Move UI and business logic to `src/features`.
12
+ - **Data Loading:** Fetch all route-level data in `loader`. Consume via `Route.useLoaderData` or `useSuspenseQuery`.
13
+ - **Guards:** Put auth, redirects, and preconditions in `beforeLoad`.
14
+ - **Hydration:** For Next.js RSC, use dehydrate(queryClient) pattern. For Start, use loader prefetching.
15
+ - **Server Functions:** Wrap all backend-only logic in standalone `serverFn`. Functions MUST act as a bridge to the API layer; keep database orchestration and business logic inside src/features/api or helpers.
16
+ - **Search Params:** Validate all search params with `validateSearch` using a Zod schema. Never trust raw search values.
17
+ - **i18n Implementation:** Use `paraglide-js` for translations. Import messages from `@/paraglide/messages`.
18
+ - **Error Handling:** Provide `errorComponent` for failure states. Handle expected errors in the loader.
19
+ - **Loading UI:** Provide `pendingComponent` for async states when needed.
20
+ - **Not Found:** Provide `notFoundComponent` for missing resources.
21
+ - **Head/SEO:** Define metadata with the `head` property. Keep it deterministic and typed.
22
+ - **Sync:** Ensure route paths are kept in sync via `tsr watch` command.
23
+ - **Guard Security:** Enforce session and permission checks within `beforeLoad` or dedicated middleware before `serverFn` execution.
24
+
25
+ ## Bans
26
+
27
+ - **Client-Side Fetching:** Fetching data inside the component body via `useEffect` or `useQuery` (without loader prefetch) is FORBIDDEN.
28
+ - **Inline serverFn:** Defining `serverFn` inside a component or route definition is FORBIDDEN. They MUST be exported as standalone constants.
29
+ - **Next.js Conventions:** Using `"use server"` directives, `page.tsx` naming, or Next.js-specific hooks (`useRouter` from next/navigation) is STRICTLY FORBIDDEN.
30
+ - **Untyped Routes:** Navigating via string paths without type-safety (using `Link` or `Maps` without the `to` property pointing to a valid route) is FORBIDDEN.
31
+ - **Insecure Env Vars:** Forbidden to store secrets or private keys in environment variables with `VITE_` prefixes.
32
+
33
+ ## Correct Implementation
34
+
35
+ <example>
36
+ // src/routes/posts/$postId.tsx
37
+ import { createFileRoute } from '@tanstack/react-router';
38
+ import { PostFeature } from '@/features/posts';
39
+ import { getPostById } from '@/features/posts/api';
40
+
41
+ export const Route = createFileRoute('/posts/$postId')({
42
+ loader: ({ params }) => getPostById(params.postId),
43
+ component: PostPage,
44
+ });
45
+
46
+ function PostPage() {
47
+ const post = Route.useLoaderData();
48
+ return <PostFeature post={post} />;
49
+ }
50
+ </example>
51
+
52
+ <example>
53
+ // src/features/auth/api/auth-actions.ts (Standalone serverFn)
54
+ import { createServerFn } from '@tanstack/start';
55
+ import { z } from 'zod';
56
+
57
+ export const loginFn = createServerFn({ method: 'POST' })
58
+ .validator(z.object({ email: z.string().email() }))
59
+ .handler(async ({ data }) => {
60
+ // Server-side logic here
61
+ return { success: true };
62
+ });
63
+ </example>
64
+
65
+ ## Incorrect Implementation
66
+
67
+ <incorrect-example>
68
+ // BAN: Data fetching inside component without loader
69
+ export const Route = createFileRoute('/dashboard')({
70
+ component: () => {
71
+ const { data } = useQuery({ queryKey: ['dash'], queryFn: fetchDash });
72
+ return <div>{data.name}</div>;
73
+ }
74
+ });
75
+ </incorrect-example>
76
+
77
+ <incorrect-example>
78
+ // BAN: Inline Next.js style server action
79
+ export const Route = createFileRoute('/login')({
80
+ component: () => {
81
+ async function action() { "use server"; ... }
82
+ return <form action={action}>...</form>;
83
+ }
84
+ });
85
+ </incorrect-example>
@@ -0,0 +1,27 @@
1
+ ---
2
+ description: "USE WHEN: Writing unit, integration, or component tests. Mandatory for logic in features."
3
+ globs: "**/*.{test,spec}.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Testing Guide (Pragmatic)
8
+
9
+ ## Principles
10
+ - **Value over Coverage:** Focus on testing complex business logic in `features/logic`. Skip simple UI components unless critical.
11
+ - [cite_start]**Behavior Testing:** Focus on user outcomes (Arrange-Act-Assert)[cite: 3].
12
+
13
+ ## Tech Stack
14
+ - [cite_start]Vitest & React Testing Library[cite: 1, 12].
15
+
16
+ ## Preferences (Not Hard Rules)
17
+ - [cite_start]**API:** Use `MSW` for stable features; simple mocks are okay for rapid prototyping[cite: 5, 8].
18
+ - [cite_start]**Location:** Keep `.test.ts` next to implementation[cite: 4].
19
+ - [cite_start]**Snapshots:** Use only for small, static data structures to prevent maintenance hell.
20
+
21
+ ## Correct Approach
22
+ <example>
23
+ it('should calculate discount correctly', () => {
24
+ const result = calculateTotal({ price: 100, discount: 20 });
25
+ expect(result).toBe(80);
26
+ });
27
+ </example>
@@ -0,0 +1,46 @@
1
+ ---
2
+ description: "USE WHEN: Defining TypeScript types, Zod schemas, and generic constraints for type safety."
3
+ globs: "**/*.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # TypeScript
8
+
9
+ ## Constraints
10
+
11
+ - **Zod-First:** Write Zod schemas for API/Domain contracts. Derive types via `z.infer`.
12
+ - **Strict:** Operate in `strict: true` mode.
13
+ - **Arrays:** Use `T[]`. Use `Array<T>` only for nested types.
14
+ - **Enums:** Use `z.enum` or `as const` objects. Native `enum` is forbidden.
15
+ - **Immutability:** Use `readonly` or `as const`.
16
+ - **Return Types:** Explicitly define return types for exported functions.
17
+ - **Generics:** Use constraints (`T extends object`).
18
+
19
+ ## Bans
20
+
21
+ - `any`.
22
+ - `as Type` (except in tests).
23
+ - `!` (Non-null assertion).
24
+ - Using Interface and Type simultaneously.
25
+ - `I` or `T` prefixes (`IUser`).
26
+ - Type soup (`Pick<Omit<Partial<...>>>`).
27
+ - Type soup (Pick<Omit<Partial<...>>> nesting > 2).
28
+ Exception: Deriving Form schemas from API schemas using Zod's `.pick()`, `.omit()`, or `.extend()` is encouraged to maintain SSOT.
29
+
30
+ ## Correct Implementation
31
+
32
+ <example>
33
+ ```ts
34
+ const UserSchema = z.object({ id: z.string() });
35
+ type User = z.infer<typeof UserSchema>;
36
+ ```
37
+ </example>
38
+
39
+ ## Incorrect Implementation
40
+
41
+ <incorrect-example>
42
+ ```ts
43
+ interface IUser { id: any; }
44
+ const user = data as User;
45
+ ```
46
+ </incorrect-example>
@@ -0,0 +1,46 @@
1
+ ---
2
+ description: "USE WHEN: Building UI components, structuring layouts, and applying styles using Tailwind CSS."
3
+ globs: "src/components/**/*.{ts,tsx},src/features/**/components/**/*.{ts,tsx}"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # UI Components
8
+
9
+ ## Constraints
10
+
11
+ - **Hierarchy:** Organize by `ui` (stateless), `shared` (common), and `feature` (domain logic).
12
+ - **Atomic:** Keep `src/components/ui` pure; forbid API/Store dependencies.
13
+ - **Styling:** Use Tailwind CSS and `cn()`. Use Tokens instead of Hex/RGB values.
14
+ - **Responsiveness:** Design mobile-first (e.g., `p-4 md:p-8`).
15
+ - **Loading:** Use Skeletons matching actual dimensions to prevent CLS.
16
+ - **A11y:** Enforce semantic HTML and `aria` attributes.
17
+ - **Exports:** Use Named exports only.
18
+
19
+ ## Bans
20
+
21
+ - Inline styles.
22
+ - CSS Modules / styled-components.
23
+ - Hex/RGB color usage (use Tokens).
24
+ - Default exports.
25
+ - Data fetching inside atomic components.
26
+ - `div` soup (use Semantic tags).
27
+
28
+ ## Correct Implementation
29
+
30
+ <example>
31
+ ```tsx
32
+ export const ProfileCard = ({ name }: { name: string }) => (
33
+ <div className={cn("p-4", "bg-muted")}>{name}</div>
34
+ );
35
+ ```
36
+ </example>
37
+
38
+ ## Incorrect Implementation
39
+
40
+ <incorrect-example>
41
+ ```tsx
42
+ export default function Button() {
43
+ return <div style={{ color: "red" }}>Click</div>;
44
+ }
45
+ ```
46
+ </incorrect-example>
@@ -0,0 +1,23 @@
1
+ # AGENTS.md
2
+
3
+ ## Persona
4
+ Frontend Architect specialized in Next.js 16 and TanStack Start. Decisions: SOLID, SRP, end-to-end type-safety. Approach: Plan-first.
5
+
6
+ ## CLI Commands
7
+ - **Dev:** `pnpm install && pnpm dev`
8
+ - **Validation:** `pnpm lint && pnpm check-types`
9
+ - **Build:** `pnpm build`
10
+
11
+ ## Operational Guardrails
12
+ - **Planning Protocol:** Approval required for: Boundaries, Routing/Rendering, State, Schemas, New Dependencies, Infrastructure.
13
+ - **Context Integrity:** Read `.mdc` files. No hallucinations for unknown paths; ask or state UNKNOWN.
14
+
15
+ ## Communication
16
+ - **Language:** Chat: Turkish. Code/Types/Naming: English.
17
+ - **Self-Documentation:** JSDoc for complex logic as per `.mdc` standards.
18
+
19
+ ## Resource Map (Progressive Disclosure)
20
+ - `.cursor/rules/core-principles.mdc` (Global Rules)
21
+ - `.cursor/rules/frontend/*.mdc` (Technical Implementation)
22
+ - `docs/architecture-guide.md` (System Design)
23
+ - `docs/MEMORIES.md` (Project Context)
@@ -0,0 +1,13 @@
1
+ # Project Memories & Context
2
+
3
+ This file serves as a persistent memory bank for the project. It documents key decisions, context, and evolution of the codebase that might not be obvious from the code itself.
4
+
5
+ ## Context
6
+ - **Project Goal:** [Brief description of what this project does]
7
+ - **Core Domain:** [Main business domain]
8
+
9
+ ## Key Decisions
10
+ - [Date] - [Decision Title]: [Description of why a certain technical choice was made]
11
+
12
+ ## Evolution
13
+ - [Date] - [Milestone]: [Description of major changes or milestones reached]
@@ -0,0 +1,100 @@
1
+ # Architecture Constitution
2
+
3
+ ## Technical Stack (SSOT)
4
+
5
+ | Layer | Technology | Authority (Rule Ref) |
6
+ | :--- | :--- | :--- |
7
+ | **Server State** | TanStack Query | `tanstack-query.mdc` |
8
+ | **Client State** | Zustand | `state-management.mdc` |
9
+ | **Validation** | Zod | `typescript.mdc` |
10
+ | **UI / Styling** | shadcn/ui + Tailwind | `ui-components.mdc` |
11
+ | **API Client** | Axios (Centralized) | `api.mdc` |
12
+
13
+ ## Framework Isolation Boundary
14
+
15
+ Implementation details for Next.js and TanStack Start are strictly segregated. Framework-specific patterns are delegated to their respective .mdc rules.
16
+
17
+ - **Next.js 16:** See `.cursor/rules/frontend/nextjs.mdc`
18
+ - **TanStack Start:** See `.cursor/rules/frontend/tanstack-start.mdc`
19
+
20
+ **Shared Layer:** Reserved strictly for framework-agnostic code (`shared/schemas`, `ui-primitives`).
21
+
22
+ ## Global Directory Hierarchy
23
+
24
+ Adhere strictly to the following tree structure. Creating arbitrary folders is FORBIDDEN:
25
+
26
+ ```text
27
+ src/
28
+ ├── app/ | routes/ # Routing layer (See Framework Rules)
29
+ ├── features/ # Domain & business logic
30
+ │ └── [feature-name]/
31
+ │ ├── api/
32
+ │ ├── components/
33
+ │ ├── helpers/
34
+ │ ├── hooks/
35
+ │ ├── schemas/
36
+ │ ├── stores/
37
+ │ ├── types/
38
+ │ └── index.ts
39
+ ├── components/
40
+ │ ├── ui/ # Atomic (shadcn)
41
+ │ ├── layout/ # Layout parts
42
+ │ └── shared/ # Reusable functional
43
+ ├── config/ # App/SEO config
44
+ ├── constants/ # Static values
45
+ ├── helpers/ # Framework-agnostic pure functions
46
+ ├── hooks/
47
+ ├── i18n/ # Localization setup
48
+ ├── lib/ # Third-party configurations
49
+ ├── messages/ # Translations
50
+ ├── providers/ # Global context
51
+ ├── schemas/ # Shared validation
52
+ ├── stores/ # Global state
53
+ ├── styles/ # Tailwind/base CSS
54
+ ├── types/ # Global TS types
55
+ └── env.ts # Env validation
56
+ ```
57
+
58
+ ## Shared vs. Feature Matrix (The Rule of Three)
59
+
60
+ Apply the following metric hierarchy to determine code location:
61
+
62
+ - **Default Scope:** All logic and components originate within `features/[feature]/`.
63
+ - **Promotion:** Any logic or component requested by 2 different features MUST be moved to the global `src/` (shared) layer.
64
+ - **Cross-Import Ban:** Direct imports between features are FORBIDDEN. Communication is restricted to the `src/shared` layer or via prop-drilling at the Page level.
65
+ - **Helpers:** Pure TypeScript functions that strictly transform input to output without side effects.
66
+ - **Lib:** Contains project-specific configured instances of external libraries. Components MUST import the wrapped instance from `src/lib` rather than the external package directly.
67
+ - **Zod Schemas:** All feature-related schemas MUST be stored in `features/[feature]/schemas/`. API functions and UI components MUST import from this single source to prevent duplication.
68
+
69
+ ## Server State & Ownership
70
+
71
+ Server state is global, but access is hierarchical:
72
+
73
+ - **Ownership:** Every API hook belongs to its respective feature. Promote to `src/hooks/api` only if shared.
74
+ - **Invalidation:** Cross-feature cache invalidation is permitted only via the global `Query Key Factory`.
75
+ - **Defaults:** StaleTime: ~60s (Lists), ~5m (Details). Centralized management: `src/providers/query-provider.tsx`.
76
+
77
+ ## Rendering & Access Control
78
+
79
+ Rendering strategies (RSC vs Client) and Data Fetching patterns are governed by the active framework's specific rule file.
80
+
81
+ - **No HTTP in UI:** UI layer is FORBIDDEN from using `axios` or `fetch` directly. Consume only `features/api` functions.
82
+ - **Insecure Scripts:** All content MUST adhere to the project's Content Security Policy; `unsafe-inline` and `unsafe-eval` are strictly forbidden.
83
+
84
+ ## Canonical Rules (MDC Refs)
85
+
86
+ This document is the architectural map. Enforceable laws are located in:
87
+
88
+ - `Ref: .cursor/rules/core-principles.mdc`
89
+ - `Ref: .cursor/rules/frontend/api.mdc`
90
+ - `Ref: .cursor/rules/frontend/forms.mdc`
91
+ - `Ref: .cursor/rules/frontend/i18n.mdc`
92
+ - `Ref: .cursor/rules/frontend/nextjs.mdc`
93
+ - `Ref: .cursor/rules/frontend/performance.mdc`
94
+ - `Ref: .cursor/rules/frontend/react-best-practices.mdc`
95
+ - `Ref: .cursor/rules/frontend/state-management.mdc`
96
+ - `Ref: .cursor/rules/frontend/tanstack-query.mdc`
97
+ - `Ref: .cursor/rules/frontend/tanstack-start.mdc`
98
+ - `Ref: .cursor/rules/frontend/testing.mdc`
99
+ - `Ref: .cursor/rules/frontend/typescript.mdc`
100
+ - `Ref: .cursor/rules/frontend/ui-components.mdc`