@mandujs/mcp 0.13.0 → 0.17.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.
Files changed (136) hide show
  1. package/README.md +102 -7
  2. package/package.json +3 -2
  3. package/src/adapters/index.ts +20 -20
  4. package/src/adapters/monitor-adapter.ts +100 -100
  5. package/src/adapters/tool-adapter.ts +88 -88
  6. package/src/executor/error-handler.ts +250 -250
  7. package/src/executor/index.ts +22 -22
  8. package/src/executor/tool-executor.ts +148 -148
  9. package/src/hooks/config-watcher.ts +174 -174
  10. package/src/hooks/index.ts +23 -23
  11. package/src/hooks/mcp-hooks.ts +227 -227
  12. package/src/logging/index.ts +15 -15
  13. package/src/logging/mcp-transport.ts +134 -134
  14. package/src/registry/index.ts +13 -13
  15. package/src/registry/mcp-tool-registry.ts +298 -298
  16. package/src/resources/skills/guides.ts +1136 -1136
  17. package/src/resources/skills/index.ts +12 -12
  18. package/src/resources/skills/loader.ts +218 -218
  19. package/src/resources/skills/mandu-composition/SKILL.md +91 -91
  20. package/src/resources/skills/mandu-composition/metadata.json +13 -13
  21. package/src/resources/skills/mandu-composition/rules/_sections.md +26 -26
  22. package/src/resources/skills/mandu-composition/rules/_template.md +77 -77
  23. package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +146 -146
  24. package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +164 -164
  25. package/src/resources/skills/mandu-composition/rules/comp-island-event.md +161 -161
  26. package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +167 -167
  27. package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +149 -149
  28. package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +148 -148
  29. package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +150 -150
  30. package/src/resources/skills/mandu-deployment/SKILL.md +92 -92
  31. package/src/resources/skills/mandu-deployment/_sections.md +41 -41
  32. package/src/resources/skills/mandu-deployment/_template.md +38 -38
  33. package/src/resources/skills/mandu-deployment/metadata.json +13 -13
  34. package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +109 -109
  35. package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +115 -115
  36. package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +219 -219
  37. package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +150 -150
  38. package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +223 -223
  39. package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +152 -152
  40. package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +179 -179
  41. package/src/resources/skills/mandu-deployment/rules/deploy-platform-supabase.md +323 -323
  42. package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +140 -140
  43. package/src/resources/skills/mandu-fs-routes/SKILL.md +82 -82
  44. package/src/resources/skills/mandu-fs-routes/metadata.json +12 -12
  45. package/src/resources/skills/mandu-fs-routes/rules/_sections.md +36 -36
  46. package/src/resources/skills/mandu-fs-routes/rules/_template.md +69 -69
  47. package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +65 -65
  48. package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +93 -93
  49. package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +55 -55
  50. package/src/resources/skills/mandu-guard/SKILL.md +129 -129
  51. package/src/resources/skills/mandu-guard/metadata.json +12 -12
  52. package/src/resources/skills/mandu-guard/rules/_sections.md +36 -36
  53. package/src/resources/skills/mandu-guard/rules/_template.md +82 -82
  54. package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +100 -100
  55. package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +76 -76
  56. package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +81 -81
  57. package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +80 -80
  58. package/src/resources/skills/mandu-hydration/SKILL.md +91 -91
  59. package/src/resources/skills/mandu-hydration/metadata.json +12 -12
  60. package/src/resources/skills/mandu-hydration/rules/_sections.md +31 -31
  61. package/src/resources/skills/mandu-hydration/rules/_template.md +72 -72
  62. package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +109 -109
  63. package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +55 -55
  64. package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +113 -113
  65. package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +68 -68
  66. package/src/resources/skills/mandu-performance/SKILL.md +85 -85
  67. package/src/resources/skills/mandu-performance/metadata.json +14 -14
  68. package/src/resources/skills/mandu-performance/rules/_sections.md +31 -31
  69. package/src/resources/skills/mandu-performance/rules/_template.md +64 -64
  70. package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +103 -103
  71. package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +95 -95
  72. package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +124 -124
  73. package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +125 -125
  74. package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +80 -80
  75. package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +145 -145
  76. package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +98 -98
  77. package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +154 -154
  78. package/src/resources/skills/mandu-security/SKILL.md +87 -87
  79. package/src/resources/skills/mandu-security/metadata.json +13 -13
  80. package/src/resources/skills/mandu-security/rules/_sections.md +31 -31
  81. package/src/resources/skills/mandu-security/rules/_template.md +74 -74
  82. package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +127 -127
  83. package/src/resources/skills/mandu-security/rules/sec-env-management.md +133 -133
  84. package/src/resources/skills/mandu-security/rules/sec-input-validate.md +148 -148
  85. package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +146 -146
  86. package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +138 -138
  87. package/src/resources/skills/mandu-slot/SKILL.md +85 -85
  88. package/src/resources/skills/mandu-slot/metadata.json +12 -12
  89. package/src/resources/skills/mandu-slot/rules/_sections.md +36 -36
  90. package/src/resources/skills/mandu-slot/rules/_template.md +63 -63
  91. package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +38 -38
  92. package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +56 -56
  93. package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +59 -59
  94. package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +64 -64
  95. package/src/resources/skills/mandu-styling/SKILL.md +154 -154
  96. package/src/resources/skills/mandu-styling/_sections.md +43 -43
  97. package/src/resources/skills/mandu-styling/_template.md +32 -32
  98. package/src/resources/skills/mandu-styling/metadata.json +15 -15
  99. package/src/resources/skills/mandu-styling/rules/style-component-compound.md +235 -235
  100. package/src/resources/skills/mandu-styling/rules/style-component-slots.md +255 -255
  101. package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +205 -205
  102. package/src/resources/skills/mandu-styling/rules/style-island-animations.md +272 -272
  103. package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +167 -167
  104. package/src/resources/skills/mandu-styling/rules/style-island-variants.md +221 -221
  105. package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +209 -209
  106. package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +192 -192
  107. package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +162 -162
  108. package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +164 -164
  109. package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +170 -170
  110. package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +179 -179
  111. package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +229 -229
  112. package/src/resources/skills/mandu-testing/SKILL.md +99 -99
  113. package/src/resources/skills/mandu-testing/metadata.json +13 -13
  114. package/src/resources/skills/mandu-testing/rules/_sections.md +26 -26
  115. package/src/resources/skills/mandu-testing/rules/_template.md +65 -65
  116. package/src/resources/skills/mandu-testing/rules/test-component-island.md +195 -195
  117. package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +196 -196
  118. package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +219 -219
  119. package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +192 -192
  120. package/src/resources/skills/mandu-ui/SKILL.md +117 -117
  121. package/src/resources/skills/mandu-ui/_sections.md +23 -23
  122. package/src/resources/skills/mandu-ui/_template.md +32 -32
  123. package/src/resources/skills/mandu-ui/metadata.json +13 -13
  124. package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +232 -232
  125. package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +238 -238
  126. package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +259 -259
  127. package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +258 -258
  128. package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +213 -213
  129. package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +209 -209
  130. package/src/resources/skills/recipes.ts +932 -932
  131. package/src/tools/ate.ts +219 -0
  132. package/src/tools/index.ts +4 -1
  133. package/src/tools/project.ts +334 -334
  134. package/src/tools/runtime.ts +497 -497
  135. package/src/tools/seo.ts +417 -417
  136. package/src/utils/withWarnings.ts +83 -83
@@ -1,229 +1,229 @@
1
- ---
2
- title: Dark Mode Implementation
3
- impact: MEDIUM
4
- impactDescription: User preference and accessibility support
5
- tags: styling, theme, darkmode, accessibility
6
- ---
7
-
8
- ## Dark Mode Implementation
9
-
10
- **Impact: MEDIUM (User preference and accessibility support)**
11
-
12
- 다크모드를 구현하여 사용자 선호도와 접근성을 지원하세요.
13
-
14
- ## CSS Variables 기반 테마
15
-
16
- ```css
17
- /* app/globals.css */
18
- @layer base {
19
- :root {
20
- --background: 0 0% 100%;
21
- --foreground: 222.2 84% 4.9%;
22
- --card: 0 0% 100%;
23
- --card-foreground: 222.2 84% 4.9%;
24
- --primary: 221.2 83.2% 53.3%;
25
- --primary-foreground: 210 40% 98%;
26
- --muted: 210 40% 96.1%;
27
- --muted-foreground: 215.4 16.3% 46.9%;
28
- --border: 214.3 31.8% 91.4%;
29
- }
30
-
31
- .dark {
32
- --background: 222.2 84% 4.9%;
33
- --foreground: 210 40% 98%;
34
- --card: 222.2 84% 4.9%;
35
- --card-foreground: 210 40% 98%;
36
- --primary: 217.2 91.2% 59.8%;
37
- --primary-foreground: 222.2 47.4% 11.2%;
38
- --muted: 217.2 32.6% 17.5%;
39
- --muted-foreground: 215 20.2% 65.1%;
40
- --border: 217.2 32.6% 17.5%;
41
- }
42
- }
43
- ```
44
-
45
- ## Tailwind dark: 활성화
46
-
47
- ```typescript
48
- // tailwind.config.ts
49
- export default {
50
- darkMode: "class", // 또는 "media"
51
- // ...
52
- };
53
- ```
54
-
55
- ## 테마 Provider Island
56
-
57
- ```tsx
58
- // app/theme/client.tsx
59
- "use client";
60
-
61
- import { createContext, useContext, useEffect, useState } from "react";
62
-
63
- type Theme = "light" | "dark" | "system";
64
-
65
- interface ThemeContextValue {
66
- theme: Theme;
67
- setTheme: (theme: Theme) => void;
68
- resolvedTheme: "light" | "dark";
69
- }
70
-
71
- const ThemeContext = createContext<ThemeContextValue | null>(null);
72
-
73
- export function ThemeProviderIsland({ children }: { children: React.ReactNode }) {
74
- const [theme, setTheme] = useState<Theme>("system");
75
- const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");
76
-
77
- useEffect(() => {
78
- // 저장된 테마 복원
79
- const stored = localStorage.getItem("theme") as Theme | null;
80
- if (stored) {
81
- setTheme(stored);
82
- }
83
- }, []);
84
-
85
- useEffect(() => {
86
- const root = document.documentElement;
87
-
88
- if (theme === "system") {
89
- const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
90
- setResolvedTheme(systemDark ? "dark" : "light");
91
- root.classList.toggle("dark", systemDark);
92
- } else {
93
- setResolvedTheme(theme);
94
- root.classList.toggle("dark", theme === "dark");
95
- }
96
-
97
- localStorage.setItem("theme", theme);
98
- }, [theme]);
99
-
100
- // System 변경 감지
101
- useEffect(() => {
102
- if (theme !== "system") return;
103
-
104
- const mq = window.matchMedia("(prefers-color-scheme: dark)");
105
- const handler = (e: MediaQueryListEvent) => {
106
- setResolvedTheme(e.matches ? "dark" : "light");
107
- document.documentElement.classList.toggle("dark", e.matches);
108
- };
109
-
110
- mq.addEventListener("change", handler);
111
- return () => mq.removeEventListener("change", handler);
112
- }, [theme]);
113
-
114
- return (
115
- <ThemeContext.Provider value={{ theme, setTheme, resolvedTheme }}>
116
- {children}
117
- </ThemeContext.Provider>
118
- );
119
- }
120
-
121
- export function useTheme() {
122
- const context = useContext(ThemeContext);
123
- if (!context) {
124
- throw new Error("useTheme must be used within ThemeProviderIsland");
125
- }
126
- return context;
127
- }
128
- ```
129
-
130
- ## 테마 토글 컴포넌트
131
-
132
- ```tsx
133
- // app/theme/toggle.tsx
134
- "use client";
135
-
136
- import { useTheme } from "./client";
137
-
138
- export function ThemeToggleIsland() {
139
- const { theme, setTheme, resolvedTheme } = useTheme();
140
-
141
- return (
142
- <button
143
- onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
144
- className="p-2 rounded-md hover:bg-muted"
145
- aria-label={`Switch to ${resolvedTheme === "dark" ? "light" : "dark"} mode`}
146
- >
147
- {resolvedTheme === "dark" ? "🌙" : "☀️"}
148
- </button>
149
- );
150
- }
151
- ```
152
-
153
- ## 플래시 방지 스크립트
154
-
155
- ```tsx
156
- // app/layout.tsx
157
- export default function RootLayout({ children }) {
158
- return (
159
- <html lang="ko" suppressHydrationWarning>
160
- <head>
161
- {/* 다크모드 플래시 방지 */}
162
- <script
163
- dangerouslySetInnerHTML={{
164
- __html: `
165
- (function() {
166
- const theme = localStorage.getItem('theme');
167
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
168
-
169
- if (theme === 'dark' || (!theme && prefersDark)) {
170
- document.documentElement.classList.add('dark');
171
- }
172
- })();
173
- `,
174
- }}
175
- />
176
- </head>
177
- <body>
178
- <ThemeProviderIsland>
179
- {children}
180
- </ThemeProviderIsland>
181
- </body>
182
- </html>
183
- );
184
- }
185
- ```
186
-
187
- ## Island 간 테마 동기화
188
-
189
- ```tsx
190
- // useIslandEvent로 테마 변경 전파
191
- import { useIslandEvent } from "@mandujs/core/client";
192
-
193
- export function ThemeProviderIsland({ children }) {
194
- const { emit } = useIslandEvent<{ theme: string }>("theme-change");
195
- const [theme, setTheme] = useState("system");
196
-
197
- const handleSetTheme = (newTheme: Theme) => {
198
- setTheme(newTheme);
199
- emit({ theme: newTheme }); // 다른 Island에 전파
200
- };
201
-
202
- // ...
203
- }
204
-
205
- // 다른 Island에서 수신
206
- export function AnotherIsland() {
207
- useIslandEvent<{ theme: string }>("theme-change", (data) => {
208
- console.log("Theme changed to:", data.theme);
209
- });
210
- }
211
- ```
212
-
213
- ## 다크모드 특화 스타일
214
-
215
- ```tsx
216
- // Tailwind dark: 접두사 사용
217
- <div className="bg-white dark:bg-gray-900">
218
- <p className="text-gray-900 dark:text-gray-100">
219
- Content
220
- </p>
221
- </div>
222
-
223
- // 복잡한 경우 CSS Variables 활용
224
- <div className="bg-[hsl(var(--background))]">
225
- {/* 자동으로 테마 반영 */}
226
- </div>
227
- ```
228
-
229
- Reference: [Tailwind Dark Mode](https://tailwindcss.com/docs/dark-mode)
1
+ ---
2
+ title: Dark Mode Implementation
3
+ impact: MEDIUM
4
+ impactDescription: User preference and accessibility support
5
+ tags: styling, theme, darkmode, accessibility
6
+ ---
7
+
8
+ ## Dark Mode Implementation
9
+
10
+ **Impact: MEDIUM (User preference and accessibility support)**
11
+
12
+ 다크모드를 구현하여 사용자 선호도와 접근성을 지원하세요.
13
+
14
+ ## CSS Variables 기반 테마
15
+
16
+ ```css
17
+ /* app/globals.css */
18
+ @layer base {
19
+ :root {
20
+ --background: 0 0% 100%;
21
+ --foreground: 222.2 84% 4.9%;
22
+ --card: 0 0% 100%;
23
+ --card-foreground: 222.2 84% 4.9%;
24
+ --primary: 221.2 83.2% 53.3%;
25
+ --primary-foreground: 210 40% 98%;
26
+ --muted: 210 40% 96.1%;
27
+ --muted-foreground: 215.4 16.3% 46.9%;
28
+ --border: 214.3 31.8% 91.4%;
29
+ }
30
+
31
+ .dark {
32
+ --background: 222.2 84% 4.9%;
33
+ --foreground: 210 40% 98%;
34
+ --card: 222.2 84% 4.9%;
35
+ --card-foreground: 210 40% 98%;
36
+ --primary: 217.2 91.2% 59.8%;
37
+ --primary-foreground: 222.2 47.4% 11.2%;
38
+ --muted: 217.2 32.6% 17.5%;
39
+ --muted-foreground: 215 20.2% 65.1%;
40
+ --border: 217.2 32.6% 17.5%;
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Tailwind dark: 활성화
46
+
47
+ ```typescript
48
+ // tailwind.config.ts
49
+ export default {
50
+ darkMode: "class", // 또는 "media"
51
+ // ...
52
+ };
53
+ ```
54
+
55
+ ## 테마 Provider Island
56
+
57
+ ```tsx
58
+ // app/theme/client.tsx
59
+ "use client";
60
+
61
+ import { createContext, useContext, useEffect, useState } from "react";
62
+
63
+ type Theme = "light" | "dark" | "system";
64
+
65
+ interface ThemeContextValue {
66
+ theme: Theme;
67
+ setTheme: (theme: Theme) => void;
68
+ resolvedTheme: "light" | "dark";
69
+ }
70
+
71
+ const ThemeContext = createContext<ThemeContextValue | null>(null);
72
+
73
+ export function ThemeProviderIsland({ children }: { children: React.ReactNode }) {
74
+ const [theme, setTheme] = useState<Theme>("system");
75
+ const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");
76
+
77
+ useEffect(() => {
78
+ // 저장된 테마 복원
79
+ const stored = localStorage.getItem("theme") as Theme | null;
80
+ if (stored) {
81
+ setTheme(stored);
82
+ }
83
+ }, []);
84
+
85
+ useEffect(() => {
86
+ const root = document.documentElement;
87
+
88
+ if (theme === "system") {
89
+ const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
90
+ setResolvedTheme(systemDark ? "dark" : "light");
91
+ root.classList.toggle("dark", systemDark);
92
+ } else {
93
+ setResolvedTheme(theme);
94
+ root.classList.toggle("dark", theme === "dark");
95
+ }
96
+
97
+ localStorage.setItem("theme", theme);
98
+ }, [theme]);
99
+
100
+ // System 변경 감지
101
+ useEffect(() => {
102
+ if (theme !== "system") return;
103
+
104
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
105
+ const handler = (e: MediaQueryListEvent) => {
106
+ setResolvedTheme(e.matches ? "dark" : "light");
107
+ document.documentElement.classList.toggle("dark", e.matches);
108
+ };
109
+
110
+ mq.addEventListener("change", handler);
111
+ return () => mq.removeEventListener("change", handler);
112
+ }, [theme]);
113
+
114
+ return (
115
+ <ThemeContext.Provider value={{ theme, setTheme, resolvedTheme }}>
116
+ {children}
117
+ </ThemeContext.Provider>
118
+ );
119
+ }
120
+
121
+ export function useTheme() {
122
+ const context = useContext(ThemeContext);
123
+ if (!context) {
124
+ throw new Error("useTheme must be used within ThemeProviderIsland");
125
+ }
126
+ return context;
127
+ }
128
+ ```
129
+
130
+ ## 테마 토글 컴포넌트
131
+
132
+ ```tsx
133
+ // app/theme/toggle.tsx
134
+ "use client";
135
+
136
+ import { useTheme } from "./client";
137
+
138
+ export function ThemeToggleIsland() {
139
+ const { theme, setTheme, resolvedTheme } = useTheme();
140
+
141
+ return (
142
+ <button
143
+ onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
144
+ className="p-2 rounded-md hover:bg-muted"
145
+ aria-label={`Switch to ${resolvedTheme === "dark" ? "light" : "dark"} mode`}
146
+ >
147
+ {resolvedTheme === "dark" ? "🌙" : "☀️"}
148
+ </button>
149
+ );
150
+ }
151
+ ```
152
+
153
+ ## 플래시 방지 스크립트
154
+
155
+ ```tsx
156
+ // app/layout.tsx
157
+ export default function RootLayout({ children }) {
158
+ return (
159
+ <html lang="ko" suppressHydrationWarning>
160
+ <head>
161
+ {/* 다크모드 플래시 방지 */}
162
+ <script
163
+ dangerouslySetInnerHTML={{
164
+ __html: `
165
+ (function() {
166
+ const theme = localStorage.getItem('theme');
167
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
168
+
169
+ if (theme === 'dark' || (!theme && prefersDark)) {
170
+ document.documentElement.classList.add('dark');
171
+ }
172
+ })();
173
+ `,
174
+ }}
175
+ />
176
+ </head>
177
+ <body>
178
+ <ThemeProviderIsland>
179
+ {children}
180
+ </ThemeProviderIsland>
181
+ </body>
182
+ </html>
183
+ );
184
+ }
185
+ ```
186
+
187
+ ## Island 간 테마 동기화
188
+
189
+ ```tsx
190
+ // useIslandEvent로 테마 변경 전파
191
+ import { useIslandEvent } from "@mandujs/core/client";
192
+
193
+ export function ThemeProviderIsland({ children }) {
194
+ const { emit } = useIslandEvent<{ theme: string }>("theme-change");
195
+ const [theme, setTheme] = useState("system");
196
+
197
+ const handleSetTheme = (newTheme: Theme) => {
198
+ setTheme(newTheme);
199
+ emit({ theme: newTheme }); // 다른 Island에 전파
200
+ };
201
+
202
+ // ...
203
+ }
204
+
205
+ // 다른 Island에서 수신
206
+ export function AnotherIsland() {
207
+ useIslandEvent<{ theme: string }>("theme-change", (data) => {
208
+ console.log("Theme changed to:", data.theme);
209
+ });
210
+ }
211
+ ```
212
+
213
+ ## 다크모드 특화 스타일
214
+
215
+ ```tsx
216
+ // Tailwind dark: 접두사 사용
217
+ <div className="bg-white dark:bg-gray-900">
218
+ <p className="text-gray-900 dark:text-gray-100">
219
+ Content
220
+ </p>
221
+ </div>
222
+
223
+ // 복잡한 경우 CSS Variables 활용
224
+ <div className="bg-[hsl(var(--background))]">
225
+ {/* 자동으로 테마 반영 */}
226
+ </div>
227
+ ```
228
+
229
+ Reference: [Tailwind Dark Mode](https://tailwindcss.com/docs/dark-mode)
@@ -1,99 +1,99 @@
1
- ---
2
- name: mandu-testing
3
- description: |
4
- Testing patterns for Mandu applications. Use when writing unit tests,
5
- integration tests, or E2E tests. Triggers on test, spec, Bun test,
6
- Playwright, or testing tasks.
7
- license: MIT
8
- metadata:
9
- author: mandu
10
- version: "1.0.0"
11
- ---
12
-
13
- # Mandu Testing
14
-
15
- Mandu 애플리케이션의 테스트 패턴 가이드. Bun test를 활용한 단위 테스트, slot 테스트, Island 컴포넌트 테스트, Playwright E2E 테스트를 다룹니다.
16
-
17
- ## When to Apply
18
-
19
- Reference these guidelines when:
20
- - Writing unit tests for slots
21
- - Testing Island components
22
- - Setting up E2E tests with Playwright
23
- - Mocking external dependencies
24
- - Testing authentication flows
25
-
26
- ## Rule Categories by Priority
27
-
28
- | Priority | Category | Impact | Prefix |
29
- |----------|----------|--------|--------|
30
- | 1 | Slot Testing | HIGH | `test-slot-` |
31
- | 2 | Component Testing | HIGH | `test-component-` |
32
- | 3 | E2E Testing | MEDIUM | `test-e2e-` |
33
- | 4 | Mocking | MEDIUM | `test-mock-` |
34
-
35
- ## Quick Reference
36
-
37
- ### 1. Slot Testing (HIGH)
38
-
39
- - `test-slot-unit` - Unit test slot handlers
40
- - `test-slot-guard` - Test guard authentication
41
- - `test-slot-integration` - Integration test with database
42
-
43
- ### 2. Component Testing (HIGH)
44
-
45
- - `test-component-island` - Test Island components
46
- - `test-component-render` - Test rendering output
47
- - `test-component-interaction` - Test user interactions
48
-
49
- ### 3. E2E Testing (MEDIUM)
50
-
51
- - `test-e2e-playwright` - Playwright setup and patterns
52
- - `test-e2e-auth` - Test authentication flows
53
- - `test-e2e-navigation` - Test page navigation
54
-
55
- ### 4. Mocking (MEDIUM)
56
-
57
- - `test-mock-fetch` - Mock fetch requests
58
- - `test-mock-database` - Mock database operations
59
-
60
- ## Bun Test Quick Start
61
-
62
- ```bash
63
- # Run all tests
64
- bun test
65
-
66
- # Run specific test file
67
- bun test src/slots/user.test.ts
68
-
69
- # Watch mode
70
- bun test --watch
71
-
72
- # Coverage
73
- bun test --coverage
74
- ```
75
-
76
- ## Test File Convention
77
-
78
- ```
79
- spec/slots/
80
- ├── users.slot.ts
81
- ├── users.slot.test.ts # Slot tests
82
- app/
83
- ├── dashboard/
84
- │ ├── client.tsx
85
- │ └── client.test.tsx # Component tests
86
- tests/
87
- └── e2e/
88
- └── auth.spec.ts # E2E tests
89
- ```
90
-
91
- ## How to Use
92
-
93
- Read individual rule files for detailed explanations:
94
-
95
- ```
96
- rules/test-slot-unit.md
97
- rules/test-component-island.md
98
- rules/test-e2e-playwright.md
99
- ```
1
+ ---
2
+ name: mandu-testing
3
+ description: |
4
+ Testing patterns for Mandu applications. Use when writing unit tests,
5
+ integration tests, or E2E tests. Triggers on test, spec, Bun test,
6
+ Playwright, or testing tasks.
7
+ license: MIT
8
+ metadata:
9
+ author: mandu
10
+ version: "1.0.0"
11
+ ---
12
+
13
+ # Mandu Testing
14
+
15
+ Mandu 애플리케이션의 테스트 패턴 가이드. Bun test를 활용한 단위 테스트, slot 테스트, Island 컴포넌트 테스트, Playwright E2E 테스트를 다룹니다.
16
+
17
+ ## When to Apply
18
+
19
+ Reference these guidelines when:
20
+ - Writing unit tests for slots
21
+ - Testing Island components
22
+ - Setting up E2E tests with Playwright
23
+ - Mocking external dependencies
24
+ - Testing authentication flows
25
+
26
+ ## Rule Categories by Priority
27
+
28
+ | Priority | Category | Impact | Prefix |
29
+ |----------|----------|--------|--------|
30
+ | 1 | Slot Testing | HIGH | `test-slot-` |
31
+ | 2 | Component Testing | HIGH | `test-component-` |
32
+ | 3 | E2E Testing | MEDIUM | `test-e2e-` |
33
+ | 4 | Mocking | MEDIUM | `test-mock-` |
34
+
35
+ ## Quick Reference
36
+
37
+ ### 1. Slot Testing (HIGH)
38
+
39
+ - `test-slot-unit` - Unit test slot handlers
40
+ - `test-slot-guard` - Test guard authentication
41
+ - `test-slot-integration` - Integration test with database
42
+
43
+ ### 2. Component Testing (HIGH)
44
+
45
+ - `test-component-island` - Test Island components
46
+ - `test-component-render` - Test rendering output
47
+ - `test-component-interaction` - Test user interactions
48
+
49
+ ### 3. E2E Testing (MEDIUM)
50
+
51
+ - `test-e2e-playwright` - Playwright setup and patterns
52
+ - `test-e2e-auth` - Test authentication flows
53
+ - `test-e2e-navigation` - Test page navigation
54
+
55
+ ### 4. Mocking (MEDIUM)
56
+
57
+ - `test-mock-fetch` - Mock fetch requests
58
+ - `test-mock-database` - Mock database operations
59
+
60
+ ## Bun Test Quick Start
61
+
62
+ ```bash
63
+ # Run all tests
64
+ bun test
65
+
66
+ # Run specific test file
67
+ bun test src/slots/user.test.ts
68
+
69
+ # Watch mode
70
+ bun test --watch
71
+
72
+ # Coverage
73
+ bun test --coverage
74
+ ```
75
+
76
+ ## Test File Convention
77
+
78
+ ```
79
+ spec/slots/
80
+ ├── users.slot.ts
81
+ ├── users.slot.test.ts # Slot tests
82
+ app/
83
+ ├── dashboard/
84
+ │ ├── client.tsx
85
+ │ └── client.test.tsx # Component tests
86
+ tests/
87
+ └── e2e/
88
+ └── auth.spec.ts # E2E tests
89
+ ```
90
+
91
+ ## How to Use
92
+
93
+ Read individual rule files for detailed explanations:
94
+
95
+ ```
96
+ rules/test-slot-unit.md
97
+ rules/test-component-island.md
98
+ rules/test-e2e-playwright.md
99
+ ```
@@ -1,13 +1,13 @@
1
- {
2
- "version": "1.0.0",
3
- "organization": "Mandu Framework",
4
- "date": "February 2026",
5
- "abstract": "Mandu 애플리케이션 테스트 패턴 가이드. Bun test를 활용한 slot 단위/통합 테스트, Island 컴포넌트 테스트, Playwright E2E 테스트, 모킹 패턴을 다룹니다.",
6
- "references": [
7
- "https://bun.sh/docs/cli/test",
8
- "https://playwright.dev/docs/intro",
9
- "https://testing-library.com/docs/react-testing-library/intro",
10
- "https://kentcdodds.com/blog/write-tests"
11
- ],
12
- "tags": ["testing", "bun-test", "playwright", "e2e", "unit", "mandu"]
13
- }
1
+ {
2
+ "version": "1.0.0",
3
+ "organization": "Mandu Framework",
4
+ "date": "February 2026",
5
+ "abstract": "Mandu 애플리케이션 테스트 패턴 가이드. Bun test를 활용한 slot 단위/통합 테스트, Island 컴포넌트 테스트, Playwright E2E 테스트, 모킹 패턴을 다룹니다.",
6
+ "references": [
7
+ "https://bun.sh/docs/cli/test",
8
+ "https://playwright.dev/docs/intro",
9
+ "https://testing-library.com/docs/react-testing-library/intro",
10
+ "https://kentcdodds.com/blog/write-tests"
11
+ ],
12
+ "tags": ["testing", "bun-test", "playwright", "e2e", "unit", "mandu"]
13
+ }