@mandujs/mcp 0.38.12 → 0.39.0-beta.1

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 (183) hide show
  1. package/README.md +3 -3
  2. package/package.json +3 -5
  3. package/src/activity-adapter.ts +23 -23
  4. package/src/activity-monitor.ts +39 -10
  5. package/src/adapters/index.ts +20 -20
  6. package/src/adapters/monitor-adapter.ts +100 -100
  7. package/src/adapters/tool-adapter.ts +90 -90
  8. package/src/executor/index.ts +22 -22
  9. package/src/executor/tool-executor.ts +148 -148
  10. package/src/hooks/config-watcher.ts +173 -173
  11. package/src/hooks/index.ts +23 -23
  12. package/src/hooks/mcp-hooks.ts +227 -227
  13. package/src/index.ts +5 -5
  14. package/src/logging/index.ts +15 -15
  15. package/src/logging/mcp-transport.ts +134 -134
  16. package/src/new-resources.ts +2 -2
  17. package/src/profiles.ts +25 -54
  18. package/src/prompts.ts +4 -4
  19. package/src/registry/index.ts +13 -13
  20. package/src/registry/mcp-tool-registry.ts +298 -298
  21. package/src/resources/generated-skills/catalog.ts +36 -0
  22. package/src/resources/generated-skills/mandu-agent-workflow/SKILL.md +48 -0
  23. package/src/resources/generated-skills/mandu-contract/SKILL.md +20 -0
  24. package/src/resources/generated-skills/mandu-fs-routes/SKILL.md +19 -0
  25. package/src/resources/generated-skills/mandu-guard/SKILL.md +20 -0
  26. package/src/resources/generated-skills/mandu-hydration/SKILL.md +19 -0
  27. package/src/resources/generated-skills/mandu-testing/SKILL.md +20 -0
  28. package/src/resources/handlers.ts +3 -3
  29. package/src/resources/skills/guides.ts +49 -49
  30. package/src/resources/skills/index.ts +12 -12
  31. package/src/resources/skills/loader.ts +8 -35
  32. package/src/resources/skills/recipes.ts +28 -28
  33. package/src/server.ts +1 -1
  34. package/src/tools/agent.ts +479 -409
  35. package/src/tools/ate-exemplar.ts +92 -92
  36. package/src/tools/ate-flakes.ts +90 -90
  37. package/src/tools/ate-mutate.ts +103 -103
  38. package/src/tools/ate-mutation-report.ts +64 -64
  39. package/src/tools/ate-oracle-pending.ts +49 -49
  40. package/src/tools/ate-oracle-replay.ts +44 -44
  41. package/src/tools/ate-oracle-verdict.ts +70 -70
  42. package/src/tools/ate-prompt.ts +146 -146
  43. package/src/tools/ate-run.ts +1 -1
  44. package/src/tools/ate.ts +38 -38
  45. package/src/tools/brain.ts +6 -6
  46. package/src/tools/composite.ts +19 -61
  47. package/src/tools/contract.ts +11 -9
  48. package/src/tools/deploy-plan.ts +2 -2
  49. package/src/tools/deploy-preview.ts +316 -316
  50. package/src/tools/design.ts +825 -825
  51. package/src/tools/docs.ts +350 -350
  52. package/src/tools/generate.ts +4 -3
  53. package/src/tools/guard.ts +1 -1
  54. package/src/tools/history.ts +1 -1
  55. package/src/tools/hydration.ts +64 -64
  56. package/src/tools/index.ts +0 -118
  57. package/src/tools/kitchen.ts +72 -72
  58. package/src/tools/lint.ts +226 -226
  59. package/src/tools/loop-close.ts +175 -175
  60. package/src/tools/negotiate.ts +263 -263
  61. package/src/tools/resource.ts +1 -1
  62. package/src/tools/run-tests.ts +424 -424
  63. package/src/tools/runtime.ts +1 -1
  64. package/src/tools/seo.ts +1 -1
  65. package/src/tools/slot-validation.ts +19 -19
  66. package/src/tools/spec.ts +201 -201
  67. package/src/tools/transaction.ts +1 -1
  68. package/src/tx-lock.ts +73 -73
  69. package/src/utils/runtime-control.ts +52 -52
  70. package/src/utils/withWarnings.ts +1 -1
  71. package/src/resources/skills/mandu-agent-workflow/SKILL.md +0 -124
  72. package/src/resources/skills/mandu-agent-workflow/metadata.json +0 -7
  73. package/src/resources/skills/mandu-composition/SKILL.md +0 -131
  74. package/src/resources/skills/mandu-composition/metadata.json +0 -13
  75. package/src/resources/skills/mandu-composition/rules/_sections.md +0 -26
  76. package/src/resources/skills/mandu-composition/rules/_template.md +0 -77
  77. package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +0 -146
  78. package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +0 -164
  79. package/src/resources/skills/mandu-composition/rules/comp-island-event.md +0 -161
  80. package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +0 -167
  81. package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +0 -149
  82. package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +0 -148
  83. package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +0 -150
  84. package/src/resources/skills/mandu-deployment/SKILL.md +0 -135
  85. package/src/resources/skills/mandu-deployment/_sections.md +0 -41
  86. package/src/resources/skills/mandu-deployment/_template.md +0 -38
  87. package/src/resources/skills/mandu-deployment/metadata.json +0 -13
  88. package/src/resources/skills/mandu-deployment/rules/db-provider-supabase.md +0 -300
  89. package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +0 -109
  90. package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +0 -115
  91. package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +0 -219
  92. package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +0 -150
  93. package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +0 -223
  94. package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +0 -152
  95. package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +0 -179
  96. package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +0 -140
  97. package/src/resources/skills/mandu-fs-routes/SKILL.md +0 -122
  98. package/src/resources/skills/mandu-fs-routes/metadata.json +0 -12
  99. package/src/resources/skills/mandu-fs-routes/rules/_sections.md +0 -36
  100. package/src/resources/skills/mandu-fs-routes/rules/_template.md +0 -69
  101. package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +0 -65
  102. package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +0 -93
  103. package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +0 -55
  104. package/src/resources/skills/mandu-guard/SKILL.md +0 -162
  105. package/src/resources/skills/mandu-guard/metadata.json +0 -12
  106. package/src/resources/skills/mandu-guard/rules/_sections.md +0 -36
  107. package/src/resources/skills/mandu-guard/rules/_template.md +0 -82
  108. package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +0 -100
  109. package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +0 -76
  110. package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +0 -81
  111. package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +0 -80
  112. package/src/resources/skills/mandu-hydration/SKILL.md +0 -139
  113. package/src/resources/skills/mandu-hydration/metadata.json +0 -12
  114. package/src/resources/skills/mandu-hydration/rules/_sections.md +0 -31
  115. package/src/resources/skills/mandu-hydration/rules/_template.md +0 -72
  116. package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +0 -109
  117. package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +0 -55
  118. package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +0 -160
  119. package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +0 -91
  120. package/src/resources/skills/mandu-performance/SKILL.md +0 -125
  121. package/src/resources/skills/mandu-performance/metadata.json +0 -14
  122. package/src/resources/skills/mandu-performance/rules/_sections.md +0 -31
  123. package/src/resources/skills/mandu-performance/rules/_template.md +0 -64
  124. package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +0 -103
  125. package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +0 -95
  126. package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +0 -124
  127. package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +0 -125
  128. package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +0 -80
  129. package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +0 -145
  130. package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +0 -98
  131. package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +0 -154
  132. package/src/resources/skills/mandu-security/SKILL.md +0 -127
  133. package/src/resources/skills/mandu-security/metadata.json +0 -13
  134. package/src/resources/skills/mandu-security/rules/_sections.md +0 -31
  135. package/src/resources/skills/mandu-security/rules/_template.md +0 -74
  136. package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +0 -127
  137. package/src/resources/skills/mandu-security/rules/sec-env-management.md +0 -133
  138. package/src/resources/skills/mandu-security/rules/sec-input-validate.md +0 -148
  139. package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +0 -146
  140. package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +0 -138
  141. package/src/resources/skills/mandu-slot/SKILL.md +0 -125
  142. package/src/resources/skills/mandu-slot/metadata.json +0 -12
  143. package/src/resources/skills/mandu-slot/rules/_sections.md +0 -36
  144. package/src/resources/skills/mandu-slot/rules/_template.md +0 -63
  145. package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +0 -38
  146. package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +0 -56
  147. package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +0 -59
  148. package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +0 -64
  149. package/src/resources/skills/mandu-styling/SKILL.md +0 -196
  150. package/src/resources/skills/mandu-styling/_sections.md +0 -43
  151. package/src/resources/skills/mandu-styling/_template.md +0 -32
  152. package/src/resources/skills/mandu-styling/metadata.json +0 -15
  153. package/src/resources/skills/mandu-styling/rules/style-component-compound.md +0 -235
  154. package/src/resources/skills/mandu-styling/rules/style-component-slots.md +0 -255
  155. package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +0 -205
  156. package/src/resources/skills/mandu-styling/rules/style-island-animations.md +0 -272
  157. package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +0 -167
  158. package/src/resources/skills/mandu-styling/rules/style-island-variants.md +0 -221
  159. package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +0 -209
  160. package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +0 -192
  161. package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +0 -162
  162. package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +0 -164
  163. package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +0 -170
  164. package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +0 -179
  165. package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +0 -229
  166. package/src/resources/skills/mandu-testing/SKILL.md +0 -132
  167. package/src/resources/skills/mandu-testing/metadata.json +0 -13
  168. package/src/resources/skills/mandu-testing/rules/_sections.md +0 -26
  169. package/src/resources/skills/mandu-testing/rules/_template.md +0 -65
  170. package/src/resources/skills/mandu-testing/rules/test-component-island.md +0 -195
  171. package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +0 -196
  172. package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +0 -219
  173. package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +0 -192
  174. package/src/resources/skills/mandu-ui/SKILL.md +0 -159
  175. package/src/resources/skills/mandu-ui/_sections.md +0 -23
  176. package/src/resources/skills/mandu-ui/_template.md +0 -32
  177. package/src/resources/skills/mandu-ui/metadata.json +0 -13
  178. package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +0 -232
  179. package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +0 -238
  180. package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +0 -259
  181. package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +0 -258
  182. package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +0 -213
  183. package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +0 -209
package/src/tx-lock.ts CHANGED
@@ -1,73 +1,73 @@
1
- /**
2
- * Transaction Lock — prevents concurrent project mutations from multiple AI agents.
3
- *
4
- * In-process singleton. If no lock exists, destructive tools work as before (backward compatible).
5
- * When a lock is held, only the holder (matching lockId) may execute destructive operations.
6
- */
7
-
8
- export interface TxLock {
9
- lockId: string;
10
- sessionId: string;
11
- acquiredAt: number;
12
- timeoutMs: number;
13
- }
14
-
15
- const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
16
-
17
- let activeLock: TxLock | null = null;
18
-
19
- function isExpired(lock: TxLock): boolean {
20
- return Date.now() - lock.acquiredAt > lock.timeoutMs;
21
- }
22
-
23
- export function acquireLock(
24
- sessionId: string,
25
- timeoutMs: number = DEFAULT_TIMEOUT_MS,
26
- ): { success: boolean; lockId?: string; error?: string } {
27
- if (activeLock) {
28
- if (isExpired(activeLock)) {
29
- activeLock = null; // auto-release stale lock
30
- } else {
31
- return {
32
- success: false,
33
- error: `Lock held by session "${activeLock.sessionId}" since ${new Date(activeLock.acquiredAt).toISOString()}`,
34
- };
35
- }
36
- }
37
- const lockId = crypto.randomUUID();
38
- activeLock = { lockId, sessionId, acquiredAt: Date.now(), timeoutMs };
39
- return { success: true, lockId };
40
- }
41
-
42
- export function releaseLock(lockId: string): boolean {
43
- if (!activeLock || activeLock.lockId !== lockId) return false;
44
- activeLock = null;
45
- return true;
46
- }
47
-
48
- export function checkLock(): {
49
- locked: boolean;
50
- lockId?: string;
51
- sessionId?: string;
52
- acquiredAt?: number;
53
- } {
54
- if (activeLock && isExpired(activeLock)) {
55
- activeLock = null;
56
- }
57
- if (!activeLock) return { locked: false };
58
- return {
59
- locked: true,
60
- lockId: activeLock.lockId,
61
- sessionId: activeLock.sessionId,
62
- acquiredAt: activeLock.acquiredAt,
63
- };
64
- }
65
-
66
- export function requireLock(lockId?: string): { allowed: boolean; error?: string } {
67
- if (!activeLock || isExpired(activeLock)) return { allowed: true };
68
- if (lockId === activeLock.lockId) return { allowed: true };
69
- return {
70
- allowed: false,
71
- error: `Project is locked by session "${activeLock.sessionId}". Provide a matching lockId or wait for expiry.`,
72
- };
73
- }
1
+ /**
2
+ * Transaction Lock — prevents concurrent project mutations from multiple AI agents.
3
+ *
4
+ * In-process singleton. If no lock exists, destructive tools work as before (backward compatible).
5
+ * When a lock is held, only the holder (matching lockId) may execute destructive operations.
6
+ */
7
+
8
+ export interface TxLock {
9
+ lockId: string;
10
+ sessionId: string;
11
+ acquiredAt: number;
12
+ timeoutMs: number;
13
+ }
14
+
15
+ const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
16
+
17
+ let activeLock: TxLock | null = null;
18
+
19
+ function isExpired(lock: TxLock): boolean {
20
+ return Date.now() - lock.acquiredAt > lock.timeoutMs;
21
+ }
22
+
23
+ export function acquireLock(
24
+ sessionId: string,
25
+ timeoutMs: number = DEFAULT_TIMEOUT_MS,
26
+ ): { success: boolean; lockId?: string; error?: string } {
27
+ if (activeLock) {
28
+ if (isExpired(activeLock)) {
29
+ activeLock = null; // auto-release stale lock
30
+ } else {
31
+ return {
32
+ success: false,
33
+ error: `Lock held by session "${activeLock.sessionId}" since ${new Date(activeLock.acquiredAt).toISOString()}`,
34
+ };
35
+ }
36
+ }
37
+ const lockId = crypto.randomUUID();
38
+ activeLock = { lockId, sessionId, acquiredAt: Date.now(), timeoutMs };
39
+ return { success: true, lockId };
40
+ }
41
+
42
+ export function releaseLock(lockId: string): boolean {
43
+ if (!activeLock || activeLock.lockId !== lockId) return false;
44
+ activeLock = null;
45
+ return true;
46
+ }
47
+
48
+ export function checkLock(): {
49
+ locked: boolean;
50
+ lockId?: string;
51
+ sessionId?: string;
52
+ acquiredAt?: number;
53
+ } {
54
+ if (activeLock && isExpired(activeLock)) {
55
+ activeLock = null;
56
+ }
57
+ if (!activeLock) return { locked: false };
58
+ return {
59
+ locked: true,
60
+ lockId: activeLock.lockId,
61
+ sessionId: activeLock.sessionId,
62
+ acquiredAt: activeLock.acquiredAt,
63
+ };
64
+ }
65
+
66
+ export function requireLock(lockId?: string): { allowed: boolean; error?: string } {
67
+ if (!activeLock || isExpired(activeLock)) return { allowed: true };
68
+ if (lockId === activeLock.lockId) return { allowed: true };
69
+ return {
70
+ allowed: false,
71
+ error: `Project is locked by session "${activeLock.sessionId}". Provide a matching lockId or wait for expiry.`,
72
+ };
73
+ }
@@ -1,52 +1,52 @@
1
- import path from "path";
2
-
3
- export interface RuntimeControlRecord {
4
- mode: "dev" | "start";
5
- port: number;
6
- token: string;
7
- baseUrl: string;
8
- startedAt: string;
9
- }
10
-
11
- const RUNTIME_CONTROL_RELATIVE_PATH = path.join(".mandu", "runtime-control.json");
12
-
13
- export async function readRuntimeControl(rootDir: string): Promise<RuntimeControlRecord | null> {
14
- try {
15
- const file = Bun.file(path.join(rootDir, RUNTIME_CONTROL_RELATIVE_PATH));
16
- if (!(await file.exists())) {
17
- return null;
18
- }
19
- return await file.json() as RuntimeControlRecord;
20
- } catch {
21
- return null;
22
- }
23
- }
24
-
25
- export async function requestRuntimeCache(
26
- rootDir: string,
27
- action: "stats" | "clear",
28
- payload: Record<string, unknown> = {}
29
- ): Promise<{ control: RuntimeControlRecord; response: Response; body: unknown } | null> {
30
- const control = await readRuntimeControl(rootDir);
31
- if (!control) {
32
- return null;
33
- }
34
-
35
- const response = await fetch(`${control.baseUrl}/_mandu/cache`, {
36
- method: action === "stats" ? "GET" : "POST",
37
- headers: {
38
- "Content-Type": "application/json",
39
- "x-mandu-control-token": control.token,
40
- },
41
- ...(action === "clear" ? { body: JSON.stringify(payload) } : {}),
42
- });
43
-
44
- let body: unknown = null;
45
- try {
46
- body = await response.json();
47
- } catch {
48
- // ignore invalid JSON
49
- }
50
-
51
- return { control, response, body };
52
- }
1
+ import path from "path";
2
+
3
+ export interface RuntimeControlRecord {
4
+ mode: "dev" | "start";
5
+ port: number;
6
+ token: string;
7
+ baseUrl: string;
8
+ startedAt: string;
9
+ }
10
+
11
+ const RUNTIME_CONTROL_RELATIVE_PATH = path.join(".mandu", "runtime-control.json");
12
+
13
+ export async function readRuntimeControl(rootDir: string): Promise<RuntimeControlRecord | null> {
14
+ try {
15
+ const file = Bun.file(path.join(rootDir, RUNTIME_CONTROL_RELATIVE_PATH));
16
+ if (!(await file.exists())) {
17
+ return null;
18
+ }
19
+ return await file.json() as RuntimeControlRecord;
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ export async function requestRuntimeCache(
26
+ rootDir: string,
27
+ action: "stats" | "clear",
28
+ payload: Record<string, unknown> = {}
29
+ ): Promise<{ control: RuntimeControlRecord; response: Response; body: unknown } | null> {
30
+ const control = await readRuntimeControl(rootDir);
31
+ if (!control) {
32
+ return null;
33
+ }
34
+
35
+ const response = await fetch(`${control.baseUrl}/_mandu/cache`, {
36
+ method: action === "stats" ? "GET" : "POST",
37
+ headers: {
38
+ "Content-Type": "application/json",
39
+ "x-mandu-control-token": control.token,
40
+ },
41
+ ...(action === "clear" ? { body: JSON.stringify(payload) } : {}),
42
+ });
43
+
44
+ let body: unknown = null;
45
+ try {
46
+ body = await response.json();
47
+ } catch {
48
+ // ignore invalid JSON
49
+ }
50
+
51
+ return { control, response, body };
52
+ }
@@ -7,7 +7,7 @@
7
7
  * MCP notification이 AI 에이전트에 전달되지 않는 문제를 해결.
8
8
  */
9
9
 
10
- import { getWatcher } from "@mandujs/core/watcher";
10
+ import { getWatcher } from "@mandujs/core/compat/watcher/index";
11
11
 
12
12
  const MUTATION_TOOLS = new Set([
13
13
  "mandu_write_slot",
@@ -1,124 +0,0 @@
1
- ---
2
- name: mandu-agent-workflow
3
- description: |
4
- Canonical Mandu agent workflow. Use first in Mandu projects before direct
5
- source edits so Codex, Claude Code, Gemini CLI, and other agents follow the
6
- same context -> plan -> apply -> verify -> repair loop.
7
- license: MIT
8
- metadata:
9
- author: mandu
10
- version: "1.0.0"
11
- ---
12
-
13
- # Mandu Agent Workflow
14
-
15
- Mandu is an agent-native fullstack framework. Agents should not begin by
16
- guessing file structure or calling low-level tools directly. Start with the
17
- official agent surface, then use domain tools only when the plan identifies a
18
- specific domain.
19
-
20
- ## When to Use
21
-
22
- Use this skill for every Mandu project task that may inspect, create, modify, or
23
- verify application code, framework configuration, contracts, slots, islands, or
24
- deployment artifacts.
25
-
26
- ## Canonical Workflow
27
-
28
- Always follow this loop:
29
-
30
- ```text
31
- context -> plan -> apply -> verify -> repair
32
- ```
33
-
34
- 1. `context`: read the project map.
35
- 2. `plan`: convert the user request into domains, files, risks, and checks.
36
- 3. `apply`: prefer intent-level MCP/domain tools; direct edits must be grounded
37
- in the plan.
38
- 4. `verify`: run the single agent-facing verification report.
39
- 5. `repair`: convert failures into next actions, then verify again.
40
-
41
- ## Preferred MCP Tools
42
-
43
- Use these first when MCP is available:
44
-
45
- | Step | Tool | Purpose |
46
- |------|------|---------|
47
- | context | `mandu.agent.context` | Project map, routes, APIs, slots, contracts, guard, diagnostics. |
48
- | plan | `mandu.agent.plan` | Deterministic task plan with domains, files, tools, risks. |
49
- | apply | `mandu.agent.apply` | Ordered action preview from `.mandu/agent-plan.json`. |
50
- | verify | `mandu.agent.verify` | Unified post-change guard/diagnose/contract report. |
51
- | repair | `mandu.agent.repair` | Structured next actions from `.mandu/agent-verify.json`. |
52
-
53
- If MCP is unavailable, use the CLI equivalents:
54
-
55
- ```bash
56
- mandu agent context --json
57
- mandu agent plan "<task>" --json --write
58
- mandu agent apply --from .mandu/agent-plan.json --json
59
- mandu agent verify --changed --json --write
60
- mandu agent repair --from .mandu/agent-verify.json --json
61
- ```
62
-
63
- ## Allowed File Edits
64
-
65
- Direct file edits are allowed only after `plan` identifies the relevant domain
66
- and the agent has inspected the local pattern. Prefer MCP/domain generation for:
67
-
68
- - pages, layouts, and API routes
69
- - contracts and OpenAPI-related files
70
- - slots and fillings
71
- - islands, partials, and hydration boundaries
72
- - deploy intent and provider artifacts
73
-
74
- Do not use destructive cleanup, cache removal, deploy execution, or broad
75
- refactors without an explicit plan and verification path.
76
-
77
- ## Domain Skill Escalation
78
-
79
- Read the matching domain skill when `mandu.agent.plan` includes that domain:
80
-
81
- | Domain | Skill |
82
- |--------|-------|
83
- | route/api | `mandu-fs-routes` |
84
- | hydration/island/partial | `mandu-hydration` |
85
- | slot/filling | `mandu-slot` |
86
- | guard/import boundary | `mandu-guard` |
87
- | test/e2e/ATE | `mandu-testing` |
88
- | deploy | `mandu-deployment` |
89
- | security/auth/session | `mandu-security` |
90
- | styling/ui/design | `mandu-styling`, `mandu-ui`, `mandu-composition` |
91
- | performance | `mandu-performance` |
92
-
93
- Domain skills are addenda. They must not replace the canonical workflow.
94
-
95
- ## Verification Command
96
-
97
- Every code-changing task should end with:
98
-
99
- ```bash
100
- mandu agent verify --changed --json --write
101
- ```
102
-
103
- Run additional commands listed in the plan or verify report, usually
104
- `bun run typecheck` and targeted `bun test` commands.
105
-
106
- ## Repair Path
107
-
108
- When verify fails:
109
-
110
- ```bash
111
- mandu agent repair --from .mandu/agent-verify.json --json
112
- ```
113
-
114
- Apply only actions that are explicitly safe and scoped. After any repair, run
115
- `mandu agent verify --changed --json --write` again.
116
-
117
- ## Common Failures
118
-
119
- - Skipping context and editing the wrong route or contract path.
120
- - Calling low-level Guard, Doctor, Fix, ATE, or deploy tools before a plan.
121
- - Treating a domain skill as the full workflow.
122
- - Ending a task after tests without writing or reading the agent verify report.
123
- - Applying broad file changes when `agent.apply` only produced a dry-run action
124
- report.
@@ -1,7 +0,0 @@
1
- {
2
- "version": "1.0.0",
3
- "organization": "Mandu Framework",
4
- "date": "May 2026",
5
- "abstract": "Canonical Mandu agent workflow for Codex, Claude Code, Gemini CLI, and other coding agents. Establishes context -> plan -> apply -> verify -> repair as the default loop and routes domain work through focused Mandu skills and MCP tools.",
6
- "tags": ["agent", "workflow", "mcp", "skills", "mandu"]
7
- }
@@ -1,131 +0,0 @@
1
- ---
2
- name: mandu-composition
3
- description: |
4
- React composition patterns for Mandu applications. Use when designing
5
- Island components, managing shared state, or building reusable component
6
- APIs. Triggers on compound components, context providers, boolean props,
7
- or component architecture tasks.
8
- license: MIT
9
- metadata:
10
- author: mandu
11
- version: "1.0.0"
12
- ---
13
-
14
- # Mandu Composition
15
-
16
- Mandu 애플리케이션을 위한 React 컴포지션 패턴 가이드. Island 컴파운드 컴포넌트, 상태 관리 인터페이스, Provider 패턴, slot-client 분리를 다룹니다. Vercel의 Composition Patterns를 Mandu 컨텍스트로 변환하여 적용합니다.
17
-
18
- ## Agent Workflow Contract
19
-
20
- This skill is a Domain addendum. It must not replace `mandu-agent-workflow`.
21
- Use it only after `mandu.agent.plan` selects composition, UI, hydration, slot, or component domains.
22
-
23
- Canonical workflow step: `plan -> apply -> verify`.
24
-
25
- Preferred MCP tools:
26
-
27
- | Step | Tools |
28
- |------|-------|
29
- | plan | `mandu.agent.plan`, `mandu.design.get`, `mandu.island.list` |
30
- | apply | `mandu.agent.apply` |
31
- | verify | `mandu.agent.verify`, `mandu.design.check`, `mandu.slot.validate` |
32
- | repair | `mandu.agent.repair` |
33
-
34
- Allowed file edits:
35
-
36
- - Island/client component files named in the plan
37
- - Provider/state modules scoped to the target feature
38
- - Slot-client boundaries only when the plan includes slot or hydration domains
39
-
40
- Verification command:
41
-
42
- ```bash
43
- mandu agent verify --changed --json --write
44
- ```
45
-
46
- Common failures:
47
-
48
- - Refactoring component APIs without checking island/client boundaries
49
- - Adding shared state providers broader than the planned feature
50
- - Mixing slot server logic into client composition files
51
-
52
- Repair path:
53
-
54
- ```bash
55
- mandu agent repair --from .mandu/agent-verify.json --json
56
- ```
57
-
58
- ## When to Apply
59
-
60
- Reference these guidelines when:
61
- - Designing Island component architecture
62
- - Managing shared state between Islands
63
- - Building reusable component APIs
64
- - Refactoring components with boolean prop proliferation
65
- - Working with compound components or context providers
66
-
67
- ## Rule Categories by Priority
68
-
69
- | Priority | Category | Impact | Prefix |
70
- |----------|----------|--------|--------|
71
- | 1 | Component Architecture | HIGH | `comp-arch-` |
72
- | 2 | State Management | HIGH | `comp-state-` |
73
- | 3 | Island Patterns | MEDIUM | `comp-island-` |
74
- | 4 | Implementation Patterns | MEDIUM | `comp-pattern-` |
75
-
76
- ## Quick Reference
77
-
78
- ### 1. Component Architecture (HIGH)
79
-
80
- - `comp-arch-avoid-boolean-props` - Use composition instead of boolean customization
81
- - `comp-arch-compound-components` - Structure Islands as compound components
82
- - `comp-arch-explicit-variants` - Create explicit variant components
83
-
84
- ### 2. State Management (HIGH)
85
-
86
- - `comp-state-context-interface` - Define generic state/actions/meta interface
87
- - `comp-state-lift-state` - Move state into provider for sibling access
88
- - `comp-state-decouple-impl` - Provider is the only place knowing implementation
89
-
90
- ### 3. Island Patterns (MEDIUM)
91
-
92
- - `comp-island-compound` - Compose Islands with shared context
93
- - `comp-island-event` - Communicate between Islands with useIslandEvent
94
- - `comp-island-slot-split` - Separate server logic (slot) from client (Island)
95
-
96
- ### 4. Implementation Patterns (MEDIUM)
97
-
98
- - `comp-pattern-children` - Use children for composition over render props
99
- - `comp-pattern-provider-boundary` - Understand provider boundary vs visual nesting
100
-
101
- ## Core Principle
102
-
103
- **Lift state, compose internals, make state dependency-injectable.**
104
-
105
- ```
106
- ┌─────────────────────────────────────────┐
107
- │ Provider (state + actions + meta) │
108
- │ ┌───────────────────────────────────┐ │
109
- │ │ Composer.Frame │ │
110
- │ │ ┌─────────┐ ┌─────────────────┐ │ │
111
- │ │ │ Input │ │ Footer │ │ │
112
- │ │ └─────────┘ │ ┌─────┐ ┌─────┐ │ │ │
113
- │ │ │ │Emoji│ │Send │ │ │ │
114
- │ │ │ └─────┘ └─────┘ │ │ │
115
- │ │ └─────────────────┘ │ │
116
- │ └───────────────────────────────────┘ │
117
- │ ┌───────────────┐ ← Outside Frame │
118
- │ │ Preview │ but inside │
119
- │ └───────────────┘ Provider! │
120
- └─────────────────────────────────────────┘
121
- ```
122
-
123
- ## How to Use
124
-
125
- Read individual rule files for detailed explanations:
126
-
127
- ```
128
- rules/comp-arch-compound-components.md
129
- rules/comp-state-context-interface.md
130
- rules/comp-island-event.md
131
- ```
@@ -1,13 +0,0 @@
1
- {
2
- "version": "1.0.0",
3
- "organization": "Mandu Framework",
4
- "date": "February 2026",
5
- "abstract": "Mandu 애플리케이션을 위한 React 컴포지션 패턴 가이드. Island 컴파운드 컴포넌트, state/actions/meta 인터페이스, Provider 패턴, useIslandEvent를 통한 Island 간 통신, slot-client 분리 패턴을 다룹니다. Vercel Composition Patterns 기반으로 Mandu 컨텍스트에 맞게 변환되었습니다.",
6
- "references": [
7
- "https://react.dev/learn/passing-data-deeply-with-context",
8
- "https://react.dev/learn/scaling-up-with-reducer-and-context",
9
- "https://www.patterns.dev/react/compound-pattern",
10
- "https://kentcdodds.com/blog/compound-components-with-react-hooks"
11
- ],
12
- "tags": ["composition", "compound", "context", "state", "island", "mandu"]
13
- }
@@ -1,26 +0,0 @@
1
- # Sections
2
-
3
- This file defines all sections, their ordering, impact levels, and descriptions.
4
- The section ID (in parentheses) is the filename prefix used to group rules.
5
-
6
- ---
7
-
8
- ## 1. Component Architecture (comp-arch)
9
-
10
- **Impact:** HIGH
11
- **Description:** Boolean props 대신 컴포지션 사용, 컴파운드 컴포넌트 구조화. 코드베이스가 확장됨에 따라 유지보수성에 큰 영향을 미칩니다.
12
-
13
- ## 2. State Management (comp-state)
14
-
15
- **Impact:** HIGH
16
- **Description:** state/actions/meta 인터페이스 정의, Provider를 통한 의존성 주입. 같은 UI를 다양한 상태 구현과 함께 재사용할 수 있게 합니다.
17
-
18
- ## 3. Island Patterns (comp-island)
19
-
20
- **Impact:** MEDIUM
21
- **Description:** Mandu Island 특화 패턴. 컴파운드 Island, Island 간 이벤트 통신, slot-client 분리를 다룹니다.
22
-
23
- ## 4. Implementation Patterns (comp-pattern)
24
-
25
- **Impact:** MEDIUM
26
- **Description:** children 활용, Provider 경계 이해 등 구현 세부 사항. 올바른 패턴 적용으로 유연성을 확보합니다.
@@ -1,77 +0,0 @@
1
- # Rule Template
2
-
3
- Use this template when creating new rules for mandu-composition.
4
-
5
- ---
6
-
7
- ```markdown
8
- ---
9
- title: Rule Title Here
10
- impact: HIGH | MEDIUM | LOW
11
- impactDescription: 영향 설명 (예: "enables flexible composition")
12
- tags: composition, tag1, tag2
13
- ---
14
-
15
- ## Rule Title Here
16
-
17
- **Impact: {LEVEL} ({impactDescription})**
18
-
19
- 규칙의 목적과 아키텍처적 영향을 설명합니다.
20
-
21
- **Incorrect (문제가 되는 패턴):**
22
-
23
- \`\`\`tsx
24
- // ❌ Boolean props로 기능 추가
25
- function Composer({
26
- showAttachments,
27
- showFormatting,
28
- showEmojis,
29
- isCompact,
30
- isReadOnly,
31
- }: Props) {
32
- return (
33
- <form>
34
- {!isReadOnly && <Input />}
35
- {showAttachments && <Attachments />}
36
- {showFormatting && <Formatting />}
37
- {showEmojis && <Emojis />}
38
- </form>
39
- );
40
- }
41
- ```
42
-
43
- **Correct (컴포지션 패턴):**
44
-
45
- \`\`\`tsx
46
- // ✅ 컴포지션으로 유연하게 구성
47
- <Composer.Provider state={state} actions={actions}>
48
- <Composer.Frame>
49
- <Composer.Input />
50
- <Composer.Footer>
51
- <Composer.Emojis />
52
- <Composer.Submit />
53
- </Composer.Footer>
54
- </Composer.Frame>
55
- </Composer.Provider>
56
- \`\`\`
57
-
58
- ## Mandu Context
59
-
60
- Mandu Island에서 이 패턴을 적용하는 방법을 설명합니다.
61
-
62
- Reference: [관련 문서 링크](https://example.com)
63
- ```
64
-
65
- ---
66
-
67
- ## Naming Convention
68
-
69
- - 파일명: `comp-{category}-{rule-name}.md`
70
- - 예시: `comp-arch-compound-components.md`, `comp-state-context-interface.md`
71
-
72
- ## Core Principle
73
-
74
- **Lift state, compose internals, make state dependency-injectable.**
75
-
76
- UI는 조합 가능한 조각들이고, 상태는 Provider가 주입합니다.
77
- Provider를 바꾸면 UI는 그대로 유지됩니다.