@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.
- package/README.md +3 -3
- package/package.json +3 -5
- package/src/activity-adapter.ts +23 -23
- package/src/activity-monitor.ts +39 -10
- package/src/adapters/index.ts +20 -20
- package/src/adapters/monitor-adapter.ts +100 -100
- package/src/adapters/tool-adapter.ts +90 -90
- package/src/executor/index.ts +22 -22
- package/src/executor/tool-executor.ts +148 -148
- package/src/hooks/config-watcher.ts +173 -173
- package/src/hooks/index.ts +23 -23
- package/src/hooks/mcp-hooks.ts +227 -227
- package/src/index.ts +5 -5
- package/src/logging/index.ts +15 -15
- package/src/logging/mcp-transport.ts +134 -134
- package/src/new-resources.ts +2 -2
- package/src/profiles.ts +25 -54
- package/src/prompts.ts +4 -4
- package/src/registry/index.ts +13 -13
- package/src/registry/mcp-tool-registry.ts +298 -298
- package/src/resources/generated-skills/catalog.ts +36 -0
- package/src/resources/generated-skills/mandu-agent-workflow/SKILL.md +48 -0
- package/src/resources/generated-skills/mandu-contract/SKILL.md +20 -0
- package/src/resources/generated-skills/mandu-fs-routes/SKILL.md +19 -0
- package/src/resources/generated-skills/mandu-guard/SKILL.md +20 -0
- package/src/resources/generated-skills/mandu-hydration/SKILL.md +19 -0
- package/src/resources/generated-skills/mandu-testing/SKILL.md +20 -0
- package/src/resources/handlers.ts +3 -3
- package/src/resources/skills/guides.ts +49 -49
- package/src/resources/skills/index.ts +12 -12
- package/src/resources/skills/loader.ts +8 -35
- package/src/resources/skills/recipes.ts +28 -28
- package/src/server.ts +1 -1
- package/src/tools/agent.ts +479 -409
- package/src/tools/ate-exemplar.ts +92 -92
- package/src/tools/ate-flakes.ts +90 -90
- package/src/tools/ate-mutate.ts +103 -103
- package/src/tools/ate-mutation-report.ts +64 -64
- package/src/tools/ate-oracle-pending.ts +49 -49
- package/src/tools/ate-oracle-replay.ts +44 -44
- package/src/tools/ate-oracle-verdict.ts +70 -70
- package/src/tools/ate-prompt.ts +146 -146
- package/src/tools/ate-run.ts +1 -1
- package/src/tools/ate.ts +38 -38
- package/src/tools/brain.ts +6 -6
- package/src/tools/composite.ts +19 -61
- package/src/tools/contract.ts +11 -9
- package/src/tools/deploy-plan.ts +2 -2
- package/src/tools/deploy-preview.ts +316 -316
- package/src/tools/design.ts +825 -825
- package/src/tools/docs.ts +350 -350
- package/src/tools/generate.ts +4 -3
- package/src/tools/guard.ts +1 -1
- package/src/tools/history.ts +1 -1
- package/src/tools/hydration.ts +64 -64
- package/src/tools/index.ts +0 -118
- package/src/tools/kitchen.ts +72 -72
- package/src/tools/lint.ts +226 -226
- package/src/tools/loop-close.ts +175 -175
- package/src/tools/negotiate.ts +263 -263
- package/src/tools/resource.ts +1 -1
- package/src/tools/run-tests.ts +424 -424
- package/src/tools/runtime.ts +1 -1
- package/src/tools/seo.ts +1 -1
- package/src/tools/slot-validation.ts +19 -19
- package/src/tools/spec.ts +201 -201
- package/src/tools/transaction.ts +1 -1
- package/src/tx-lock.ts +73 -73
- package/src/utils/runtime-control.ts +52 -52
- package/src/utils/withWarnings.ts +1 -1
- package/src/resources/skills/mandu-agent-workflow/SKILL.md +0 -124
- package/src/resources/skills/mandu-agent-workflow/metadata.json +0 -7
- package/src/resources/skills/mandu-composition/SKILL.md +0 -131
- package/src/resources/skills/mandu-composition/metadata.json +0 -13
- package/src/resources/skills/mandu-composition/rules/_sections.md +0 -26
- package/src/resources/skills/mandu-composition/rules/_template.md +0 -77
- package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +0 -146
- package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +0 -164
- package/src/resources/skills/mandu-composition/rules/comp-island-event.md +0 -161
- package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +0 -167
- package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +0 -149
- package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +0 -148
- package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +0 -150
- package/src/resources/skills/mandu-deployment/SKILL.md +0 -135
- package/src/resources/skills/mandu-deployment/_sections.md +0 -41
- package/src/resources/skills/mandu-deployment/_template.md +0 -38
- package/src/resources/skills/mandu-deployment/metadata.json +0 -13
- package/src/resources/skills/mandu-deployment/rules/db-provider-supabase.md +0 -300
- package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +0 -109
- package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +0 -115
- package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +0 -219
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +0 -150
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +0 -223
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +0 -152
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +0 -179
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +0 -140
- package/src/resources/skills/mandu-fs-routes/SKILL.md +0 -122
- package/src/resources/skills/mandu-fs-routes/metadata.json +0 -12
- package/src/resources/skills/mandu-fs-routes/rules/_sections.md +0 -36
- package/src/resources/skills/mandu-fs-routes/rules/_template.md +0 -69
- package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +0 -65
- package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +0 -93
- package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +0 -55
- package/src/resources/skills/mandu-guard/SKILL.md +0 -162
- package/src/resources/skills/mandu-guard/metadata.json +0 -12
- package/src/resources/skills/mandu-guard/rules/_sections.md +0 -36
- package/src/resources/skills/mandu-guard/rules/_template.md +0 -82
- package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +0 -100
- package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +0 -76
- package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +0 -81
- package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +0 -80
- package/src/resources/skills/mandu-hydration/SKILL.md +0 -139
- package/src/resources/skills/mandu-hydration/metadata.json +0 -12
- package/src/resources/skills/mandu-hydration/rules/_sections.md +0 -31
- package/src/resources/skills/mandu-hydration/rules/_template.md +0 -72
- package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +0 -109
- package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +0 -55
- package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +0 -160
- package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +0 -91
- package/src/resources/skills/mandu-performance/SKILL.md +0 -125
- package/src/resources/skills/mandu-performance/metadata.json +0 -14
- package/src/resources/skills/mandu-performance/rules/_sections.md +0 -31
- package/src/resources/skills/mandu-performance/rules/_template.md +0 -64
- package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +0 -103
- package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +0 -95
- package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +0 -124
- package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +0 -125
- package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +0 -80
- package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +0 -145
- package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +0 -98
- package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +0 -154
- package/src/resources/skills/mandu-security/SKILL.md +0 -127
- package/src/resources/skills/mandu-security/metadata.json +0 -13
- package/src/resources/skills/mandu-security/rules/_sections.md +0 -31
- package/src/resources/skills/mandu-security/rules/_template.md +0 -74
- package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +0 -127
- package/src/resources/skills/mandu-security/rules/sec-env-management.md +0 -133
- package/src/resources/skills/mandu-security/rules/sec-input-validate.md +0 -148
- package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +0 -146
- package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +0 -138
- package/src/resources/skills/mandu-slot/SKILL.md +0 -125
- package/src/resources/skills/mandu-slot/metadata.json +0 -12
- package/src/resources/skills/mandu-slot/rules/_sections.md +0 -36
- package/src/resources/skills/mandu-slot/rules/_template.md +0 -63
- package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +0 -38
- package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +0 -56
- package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +0 -59
- package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +0 -64
- package/src/resources/skills/mandu-styling/SKILL.md +0 -196
- package/src/resources/skills/mandu-styling/_sections.md +0 -43
- package/src/resources/skills/mandu-styling/_template.md +0 -32
- package/src/resources/skills/mandu-styling/metadata.json +0 -15
- package/src/resources/skills/mandu-styling/rules/style-component-compound.md +0 -235
- package/src/resources/skills/mandu-styling/rules/style-component-slots.md +0 -255
- package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +0 -205
- package/src/resources/skills/mandu-styling/rules/style-island-animations.md +0 -272
- package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +0 -167
- package/src/resources/skills/mandu-styling/rules/style-island-variants.md +0 -221
- package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +0 -209
- package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +0 -192
- package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +0 -162
- package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +0 -164
- package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +0 -170
- package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +0 -179
- package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +0 -229
- package/src/resources/skills/mandu-testing/SKILL.md +0 -132
- package/src/resources/skills/mandu-testing/metadata.json +0 -13
- package/src/resources/skills/mandu-testing/rules/_sections.md +0 -26
- package/src/resources/skills/mandu-testing/rules/_template.md +0 -65
- package/src/resources/skills/mandu-testing/rules/test-component-island.md +0 -195
- package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +0 -196
- package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +0 -219
- package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +0 -192
- package/src/resources/skills/mandu-ui/SKILL.md +0 -159
- package/src/resources/skills/mandu-ui/_sections.md +0 -23
- package/src/resources/skills/mandu-ui/_template.md +0 -32
- package/src/resources/skills/mandu-ui/metadata.json +0 -13
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +0 -232
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +0 -238
- package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +0 -259
- package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +0 -258
- package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +0 -213
- package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +0 -209
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use Context Response Methods
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: Consistent API responses
|
|
5
|
-
tags: slot, context, response
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use Context Response Methods
|
|
9
|
-
|
|
10
|
-
Use `ctx.ok()`, `ctx.created()`, `ctx.error()` instead of manual Response objects.
|
|
11
|
-
These methods ensure consistent response format across your API.
|
|
12
|
-
|
|
13
|
-
**Incorrect (manual Response):**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
export default Mandu.filling()
|
|
17
|
-
.get((ctx) => {
|
|
18
|
-
return new Response(JSON.stringify({ data: [] }), {
|
|
19
|
-
headers: { "Content-Type": "application/json" }
|
|
20
|
-
});
|
|
21
|
-
})
|
|
22
|
-
.post(async (ctx) => {
|
|
23
|
-
return new Response(JSON.stringify({ error: "Bad request" }), {
|
|
24
|
-
status: 400
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Correct (context methods):**
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
export default Mandu.filling()
|
|
33
|
-
.get((ctx) => {
|
|
34
|
-
return ctx.ok({ data: [] });
|
|
35
|
-
})
|
|
36
|
-
.post(async (ctx) => {
|
|
37
|
-
const body = await ctx.body();
|
|
38
|
-
if (!body.name) {
|
|
39
|
-
return ctx.error("name is required");
|
|
40
|
-
}
|
|
41
|
-
return ctx.created({ data: body });
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Response Methods
|
|
46
|
-
|
|
47
|
-
| Method | Status | Use Case |
|
|
48
|
-
|--------|--------|----------|
|
|
49
|
-
| `ctx.ok(data)` | 200 | Success |
|
|
50
|
-
| `ctx.created(data)` | 201 | Resource created |
|
|
51
|
-
| `ctx.noContent()` | 204 | Success, no body |
|
|
52
|
-
| `ctx.error(msg)` | 400 | Bad request |
|
|
53
|
-
| `ctx.unauthorized(msg)` | 401 | Auth required |
|
|
54
|
-
| `ctx.forbidden(msg)` | 403 | Permission denied |
|
|
55
|
-
| `ctx.notFound(msg)` | 404 | Not found |
|
|
56
|
-
| `ctx.fail(msg)` | 500 | Server error |
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use .guard() for Authentication
|
|
3
|
-
impact: MEDIUM
|
|
4
|
-
impactDescription: Clean auth separation
|
|
5
|
-
tags: slot, guard, authentication
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use .guard() for Authentication
|
|
9
|
-
|
|
10
|
-
Use `.guard()` to check authentication before handlers run. Return a response
|
|
11
|
-
to block the request, or return void/undefined to continue.
|
|
12
|
-
|
|
13
|
-
**Incorrect (auth check in every handler):**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
export default Mandu.filling()
|
|
17
|
-
.get((ctx) => {
|
|
18
|
-
const user = ctx.get("user");
|
|
19
|
-
if (!user) {
|
|
20
|
-
return ctx.unauthorized("Login required");
|
|
21
|
-
}
|
|
22
|
-
return ctx.ok({ data: [] });
|
|
23
|
-
})
|
|
24
|
-
.post(async (ctx) => {
|
|
25
|
-
const user = ctx.get("user");
|
|
26
|
-
if (!user) {
|
|
27
|
-
return ctx.unauthorized("Login required");
|
|
28
|
-
}
|
|
29
|
-
// ... create logic
|
|
30
|
-
});
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**Correct (single guard):**
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
export default Mandu.filling()
|
|
37
|
-
.guard((ctx) => {
|
|
38
|
-
const user = ctx.get("user");
|
|
39
|
-
if (!user) {
|
|
40
|
-
return ctx.unauthorized("Login required");
|
|
41
|
-
}
|
|
42
|
-
// void return = continue to handlers
|
|
43
|
-
})
|
|
44
|
-
.get((ctx) => {
|
|
45
|
-
const user = ctx.get("user");
|
|
46
|
-
return ctx.ok({ data: [], user });
|
|
47
|
-
})
|
|
48
|
-
.post(async (ctx) => {
|
|
49
|
-
const body = await ctx.body();
|
|
50
|
-
return ctx.created({ data: body });
|
|
51
|
-
});
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Guard Rules
|
|
55
|
-
|
|
56
|
-
1. Return response → Request blocked
|
|
57
|
-
2. Return void → Continue to handler
|
|
58
|
-
3. Guard runs before ALL HTTP method handlers
|
|
59
|
-
4. Use `.onRequest()` to set user before guard runs
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use Appropriate HTTP Methods
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: RESTful API design
|
|
5
|
-
tags: slot, http, methods, rest
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use Appropriate HTTP Methods
|
|
9
|
-
|
|
10
|
-
Chain HTTP methods on Mandu.filling() for RESTful API design.
|
|
11
|
-
|
|
12
|
-
**Incorrect (single handler for all):**
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
export default Mandu.filling()
|
|
16
|
-
.get(async (ctx) => {
|
|
17
|
-
const method = ctx.req.method;
|
|
18
|
-
if (method === "GET") {
|
|
19
|
-
return ctx.ok({ data: [] });
|
|
20
|
-
} else if (method === "POST") {
|
|
21
|
-
const body = await ctx.body();
|
|
22
|
-
return ctx.created({ data: body });
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Correct (separate methods):**
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
export default Mandu.filling()
|
|
31
|
-
.get((ctx) => {
|
|
32
|
-
// GET /api/users - List users
|
|
33
|
-
return ctx.ok({ data: [] });
|
|
34
|
-
})
|
|
35
|
-
.post(async (ctx) => {
|
|
36
|
-
// POST /api/users - Create user
|
|
37
|
-
const body = await ctx.body<{ name: string }>();
|
|
38
|
-
return ctx.created({ data: { id: 1, ...body } });
|
|
39
|
-
})
|
|
40
|
-
.put(async (ctx) => {
|
|
41
|
-
// PUT /api/users/:id - Replace user
|
|
42
|
-
const body = await ctx.body();
|
|
43
|
-
return ctx.ok({ data: body });
|
|
44
|
-
})
|
|
45
|
-
.patch(async (ctx) => {
|
|
46
|
-
// PATCH /api/users/:id - Update user
|
|
47
|
-
const body = await ctx.body();
|
|
48
|
-
return ctx.ok({ data: body });
|
|
49
|
-
})
|
|
50
|
-
.delete((ctx) => {
|
|
51
|
-
// DELETE /api/users/:id - Delete user
|
|
52
|
-
return ctx.noContent();
|
|
53
|
-
});
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## HTTP Method Semantics
|
|
57
|
-
|
|
58
|
-
| Method | Idempotent | Use Case |
|
|
59
|
-
|--------|------------|----------|
|
|
60
|
-
| GET | Yes | Read resource |
|
|
61
|
-
| POST | No | Create resource |
|
|
62
|
-
| PUT | Yes | Replace resource |
|
|
63
|
-
| PATCH | No | Partial update |
|
|
64
|
-
| DELETE | Yes | Remove resource |
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Mandu Styling
|
|
3
|
-
description: Tailwind CSS v4 integration and Island styling patterns for Mandu Framework
|
|
4
|
-
metadata:
|
|
5
|
-
version: "2.0.0"
|
|
6
|
-
author: mandu
|
|
7
|
-
tailwind: "v4.1+"
|
|
8
|
-
globs:
|
|
9
|
-
- "**/*.css"
|
|
10
|
-
- "**/*.module.css"
|
|
11
|
-
- "app/globals.css"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# Mandu Styling Skill
|
|
15
|
-
|
|
16
|
-
Mandu Island 아키텍처에 최적화된 Tailwind CSS v4 스타일링 가이드입니다.
|
|
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 styling, design, UI, hydration, 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` |
|
|
30
|
-
| apply | `mandu.agent.apply`, `mandu.design.patch` |
|
|
31
|
-
| verify | `mandu.agent.verify`, `mandu.design.check`, `mandu.lint` |
|
|
32
|
-
| repair | `mandu.agent.repair` |
|
|
33
|
-
|
|
34
|
-
Allowed file edits:
|
|
35
|
-
|
|
36
|
-
- CSS files named in the plan, especially `app/globals.css`
|
|
37
|
-
- Component className changes scoped to the target UI
|
|
38
|
-
- Theme tokens only after inspecting the project's design source
|
|
39
|
-
|
|
40
|
-
Verification command:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
mandu agent verify --changed --json --write
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Common failures:
|
|
47
|
-
|
|
48
|
-
- Installing or changing styling stacks before checking the existing project style
|
|
49
|
-
- Editing broad theme tokens for a local component issue
|
|
50
|
-
- Skipping design/lint verification after Tailwind v4 syntax changes
|
|
51
|
-
|
|
52
|
-
Repair path:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
mandu agent repair --from .mandu/agent-verify.json --json
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## 핵심 원칙
|
|
59
|
-
|
|
60
|
-
1. **Zero-Runtime**: 빌드 타임 CSS 생성 (SSR 호환)
|
|
61
|
-
2. **CSS-First**: JavaScript 설정 대신 CSS에서 테마 정의
|
|
62
|
-
3. **Island 격리**: 컴포넌트 간 스타일 충돌 방지
|
|
63
|
-
4. **Auto Integration**: Mandu가 Tailwind v4 자동 감지 및 빌드
|
|
64
|
-
|
|
65
|
-
## 권장 스택
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
Primary: Tailwind CSS v4 + clsx/tailwind-merge
|
|
69
|
-
Alternative: CSS Modules (최소 의존성)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Setup Examples
|
|
73
|
-
|
|
74
|
-
Use these examples only after `mandu.agent.plan` selects styling setup or migration.
|
|
75
|
-
|
|
76
|
-
### 1. 설치
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
bun add -d tailwindcss@^4.1 @tailwindcss/cli@^4.1
|
|
80
|
-
bun add clsx tailwind-merge
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 2. app/globals.css
|
|
84
|
-
|
|
85
|
-
```css
|
|
86
|
-
@import "tailwindcss";
|
|
87
|
-
|
|
88
|
-
@theme {
|
|
89
|
-
--color-primary: hsl(222.2 47.4% 11.2%);
|
|
90
|
-
--color-primary-foreground: hsl(210 40% 98%);
|
|
91
|
-
--color-background: hsl(0 0% 100%);
|
|
92
|
-
--color-foreground: hsl(222.2 84% 4.9%);
|
|
93
|
-
--radius-md: 0.5rem;
|
|
94
|
-
--font-sans: 'Inter', system-ui, sans-serif;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
body {
|
|
98
|
-
background-color: var(--color-background);
|
|
99
|
-
color: var(--color-foreground);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### 3. Mandu 자동 통합
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
mandu dev 실행 시:
|
|
107
|
-
├─ @import "tailwindcss" 감지
|
|
108
|
-
├─ Tailwind CLI --watch 자동 시작
|
|
109
|
-
├─ 출력: .mandu/client/globals.css
|
|
110
|
-
├─ SSR에서 <link> 자동 주입
|
|
111
|
-
└─ CSS 변경 시 HMR 핫 리로드
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## Island 스타일링
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
// src/client/widgets/counter/Counter.island.tsx
|
|
118
|
-
"use client";
|
|
119
|
-
|
|
120
|
-
import { cn } from "@/shared/lib/utils";
|
|
121
|
-
|
|
122
|
-
export function CounterIsland({ variant = "default" }) {
|
|
123
|
-
return (
|
|
124
|
-
<button className={cn(
|
|
125
|
-
"px-4 py-2 rounded-md font-medium transition-colors",
|
|
126
|
-
variant === "default"
|
|
127
|
-
? "bg-primary text-primary-foreground hover:bg-primary/90"
|
|
128
|
-
: "border border-primary text-primary hover:bg-primary/10"
|
|
129
|
-
)}>
|
|
130
|
-
Count: 0
|
|
131
|
-
</button>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## cn 유틸리티
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
// src/client/shared/lib/utils.ts
|
|
140
|
-
import { clsx, type ClassValue } from "clsx";
|
|
141
|
-
import { twMerge } from "tailwind-merge";
|
|
142
|
-
|
|
143
|
-
export function cn(...inputs: ClassValue[]) {
|
|
144
|
-
return twMerge(clsx(inputs));
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Custom Utilities
|
|
149
|
-
|
|
150
|
-
```css
|
|
151
|
-
/* v4 방식: @utility 사용 */
|
|
152
|
-
@utility text-balance {
|
|
153
|
-
text-wrap: balance;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
@utility scrollbar-hide {
|
|
157
|
-
-ms-overflow-style: none;
|
|
158
|
-
scrollbar-width: none;
|
|
159
|
-
&::-webkit-scrollbar { display: none; }
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## v4 주요 변경사항
|
|
164
|
-
|
|
165
|
-
| v3 | v4 |
|
|
166
|
-
|----|-----|
|
|
167
|
-
| `@tailwind base/utilities` | `@import "tailwindcss"` |
|
|
168
|
-
| `tailwind.config.ts` | `@theme { }` in CSS |
|
|
169
|
-
| `!bg-red-500` | `bg-red-500!` |
|
|
170
|
-
| `@layer utilities` | `@utility` |
|
|
171
|
-
| `bg-[--var]` | `bg-(--var)` |
|
|
172
|
-
|
|
173
|
-
> 자세한 내용은 `rules/style-tailwind-v4-gotchas.md` 참조
|
|
174
|
-
|
|
175
|
-
## 규칙 카테고리
|
|
176
|
-
|
|
177
|
-
| Category | Description | Rules |
|
|
178
|
-
|----------|-------------|-------|
|
|
179
|
-
| Setup | Tailwind v4 설정 | 1 |
|
|
180
|
-
| Gotchas | v4 주의사항/마이그레이션 | 1 |
|
|
181
|
-
| Island | Island 스타일 패턴 | 3 |
|
|
182
|
-
| Component | 컴포넌트 스타일 | 3 |
|
|
183
|
-
| Performance | 최적화 | 2 |
|
|
184
|
-
| Theme | 테마/다크모드 | 1 |
|
|
185
|
-
|
|
186
|
-
→ 세부 규칙은 `rules/` 폴더 참조
|
|
187
|
-
|
|
188
|
-
## Browser Support
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
Safari 16.4+ | Chrome 111+ | Firefox 128+
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
> IE 및 구형 브라우저 미지원. 레거시 프로젝트는 Tailwind v3 유지 권장.
|
|
195
|
-
|
|
196
|
-
Reference: [Tailwind CSS v4](https://tailwindcss.com/docs)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Mandu Styling - Rule Categories
|
|
2
|
-
|
|
3
|
-
## Setup
|
|
4
|
-
CSS 프레임워크 초기 설정 및 Mandu 통합 (Tailwind v4 CSS-first)
|
|
5
|
-
|
|
6
|
-
| Impact | Description |
|
|
7
|
-
|--------|-------------|
|
|
8
|
-
| CRITICAL | 프레임워크 설정 없이 스타일링 불가 |
|
|
9
|
-
|
|
10
|
-
## Gotchas
|
|
11
|
-
Tailwind CSS v4 마이그레이션 주의사항 및 Breaking Changes
|
|
12
|
-
|
|
13
|
-
| Impact | Description |
|
|
14
|
-
|--------|-------------|
|
|
15
|
-
| HIGH | v3→v4 마이그레이션 시 필수 확인 사항 |
|
|
16
|
-
|
|
17
|
-
## Island
|
|
18
|
-
Island 컴포넌트 특화 스타일링 패턴
|
|
19
|
-
|
|
20
|
-
| Impact | Description |
|
|
21
|
-
|--------|-------------|
|
|
22
|
-
| HIGH | 스타일 충돌 방지, 독립적 hydration 지원 |
|
|
23
|
-
|
|
24
|
-
## Component
|
|
25
|
-
컴포넌트 레벨 스타일링 패턴
|
|
26
|
-
|
|
27
|
-
| Impact | Description |
|
|
28
|
-
|--------|-------------|
|
|
29
|
-
| HIGH | 재사용성, 일관성, 유지보수성 향상 |
|
|
30
|
-
|
|
31
|
-
## Performance
|
|
32
|
-
CSS 빌드 및 로딩 최적화
|
|
33
|
-
|
|
34
|
-
| Impact | Description |
|
|
35
|
-
|--------|-------------|
|
|
36
|
-
| MEDIUM | 번들 크기, 초기 로딩 성능 개선 |
|
|
37
|
-
|
|
38
|
-
## Theme
|
|
39
|
-
다크모드 및 테마 시스템
|
|
40
|
-
|
|
41
|
-
| Impact | Description |
|
|
42
|
-
|--------|-------------|
|
|
43
|
-
| MEDIUM | 사용자 경험, 접근성 향상 |
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Rule Title Here
|
|
3
|
-
impact: CRITICAL | HIGH | MEDIUM | LOW
|
|
4
|
-
impactDescription: One-line description of why this matters
|
|
5
|
-
tags: styling, tag2, tag3
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Rule Title Here
|
|
9
|
-
|
|
10
|
-
**Impact: LEVEL (Impact description)**
|
|
11
|
-
|
|
12
|
-
규칙에 대한 간단한 설명.
|
|
13
|
-
|
|
14
|
-
**설정:**
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
// 설정 예시
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
**사용 예시:**
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
// 컴포넌트 예시
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 추가 패턴
|
|
27
|
-
|
|
28
|
-
```tsx
|
|
29
|
-
// 추가 패턴
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Reference: [문서 링크](https://example.com)
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "mandu-styling",
|
|
3
|
-
"name": "Mandu Styling",
|
|
4
|
-
"version": "2.0.0",
|
|
5
|
-
"description": "Tailwind CSS v4 integration and Island styling patterns for Mandu Framework",
|
|
6
|
-
"author": "mandu",
|
|
7
|
-
"tailwind": "v4.1+",
|
|
8
|
-
"references": [
|
|
9
|
-
"https://tailwindcss.com/docs",
|
|
10
|
-
"https://tailwindcss.com/docs/upgrade-guide",
|
|
11
|
-
"https://panda-css.com/docs",
|
|
12
|
-
"https://lightningcss.dev/"
|
|
13
|
-
],
|
|
14
|
-
"abstract": "Mandu Island 아키텍처에 최적화된 Tailwind CSS v4 스타일링 가이드. CSS-first 설정, @theme 블록, Mandu 자동 통합(CSS Auto-Build, HMR)을 지원합니다."
|
|
15
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Compound Component Styling
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: Consistent styling for compound component patterns
|
|
5
|
-
tags: styling, compound, composition, patterns
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Compound Component Styling
|
|
9
|
-
|
|
10
|
-
**Impact: HIGH (Consistent styling for compound component patterns)**
|
|
11
|
-
|
|
12
|
-
Mandu의 compound component 패턴에 맞는 스타일링 방법입니다.
|
|
13
|
-
|
|
14
|
-
## 기본 패턴
|
|
15
|
-
|
|
16
|
-
```tsx
|
|
17
|
-
// app/card/client.tsx
|
|
18
|
-
"use client";
|
|
19
|
-
|
|
20
|
-
import { createContext, useContext } from "react";
|
|
21
|
-
import { cn } from "@/lib/utils";
|
|
22
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
23
|
-
|
|
24
|
-
// 1. Variants 정의
|
|
25
|
-
const cardVariants = cva("rounded-lg border", {
|
|
26
|
-
variants: {
|
|
27
|
-
variant: {
|
|
28
|
-
default: "bg-card text-card-foreground",
|
|
29
|
-
elevated: "bg-card shadow-lg",
|
|
30
|
-
ghost: "border-transparent",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
defaultVariants: {
|
|
34
|
-
variant: "default",
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// 2. Context로 variant 공유
|
|
39
|
-
type CardContextValue = VariantProps<typeof cardVariants>;
|
|
40
|
-
const CardContext = createContext<CardContextValue>({});
|
|
41
|
-
|
|
42
|
-
// 3. Compound 컴포넌트
|
|
43
|
-
export const Card = {
|
|
44
|
-
Root: ({
|
|
45
|
-
variant,
|
|
46
|
-
className,
|
|
47
|
-
children,
|
|
48
|
-
...props
|
|
49
|
-
}: React.HTMLAttributes<HTMLDivElement> & CardContextValue) => (
|
|
50
|
-
<CardContext.Provider value={{ variant }}>
|
|
51
|
-
<div className={cn(cardVariants({ variant }), className)} {...props}>
|
|
52
|
-
{children}
|
|
53
|
-
</div>
|
|
54
|
-
</CardContext.Provider>
|
|
55
|
-
),
|
|
56
|
-
|
|
57
|
-
Header: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
|
58
|
-
<div className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
|
|
59
|
-
),
|
|
60
|
-
|
|
61
|
-
Title: ({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) => (
|
|
62
|
-
<h3 className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
|
|
63
|
-
),
|
|
64
|
-
|
|
65
|
-
Description: ({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => (
|
|
66
|
-
<p className={cn("text-sm text-muted-foreground", className)} {...props} />
|
|
67
|
-
),
|
|
68
|
-
|
|
69
|
-
Content: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
|
70
|
-
<div className={cn("p-6 pt-0", className)} {...props} />
|
|
71
|
-
),
|
|
72
|
-
|
|
73
|
-
Footer: ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
|
74
|
-
<div className={cn("flex items-center p-6 pt-0", className)} {...props} />
|
|
75
|
-
),
|
|
76
|
-
};
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 사용 예시
|
|
80
|
-
|
|
81
|
-
```tsx
|
|
82
|
-
<Card.Root variant="elevated">
|
|
83
|
-
<Card.Header>
|
|
84
|
-
<Card.Title>Card Title</Card.Title>
|
|
85
|
-
<Card.Description>Card description</Card.Description>
|
|
86
|
-
</Card.Header>
|
|
87
|
-
<Card.Content>
|
|
88
|
-
Content here
|
|
89
|
-
</Card.Content>
|
|
90
|
-
<Card.Footer>
|
|
91
|
-
<button>Action</button>
|
|
92
|
-
</Card.Footer>
|
|
93
|
-
</Card.Root>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Context 기반 스타일 상속
|
|
97
|
-
|
|
98
|
-
```tsx
|
|
99
|
-
// app/alert/client.tsx
|
|
100
|
-
"use client";
|
|
101
|
-
|
|
102
|
-
import { createContext, useContext } from "react";
|
|
103
|
-
|
|
104
|
-
type AlertVariant = "default" | "info" | "success" | "warning" | "error";
|
|
105
|
-
|
|
106
|
-
const AlertContext = createContext<{ variant: AlertVariant }>({
|
|
107
|
-
variant: "default",
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
const alertStyles = {
|
|
111
|
-
default: {
|
|
112
|
-
root: "bg-background text-foreground",
|
|
113
|
-
icon: "text-foreground",
|
|
114
|
-
},
|
|
115
|
-
info: {
|
|
116
|
-
root: "bg-blue-50 text-blue-900 border-blue-200",
|
|
117
|
-
icon: "text-blue-600",
|
|
118
|
-
},
|
|
119
|
-
success: {
|
|
120
|
-
root: "bg-green-50 text-green-900 border-green-200",
|
|
121
|
-
icon: "text-green-600",
|
|
122
|
-
},
|
|
123
|
-
warning: {
|
|
124
|
-
root: "bg-yellow-50 text-yellow-900 border-yellow-200",
|
|
125
|
-
icon: "text-yellow-600",
|
|
126
|
-
},
|
|
127
|
-
error: {
|
|
128
|
-
root: "bg-red-50 text-red-900 border-red-200",
|
|
129
|
-
icon: "text-red-600",
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export const Alert = {
|
|
134
|
-
Root: ({ variant = "default", className, ...props }) => (
|
|
135
|
-
<AlertContext.Provider value={{ variant }}>
|
|
136
|
-
<div
|
|
137
|
-
role="alert"
|
|
138
|
-
className={cn(
|
|
139
|
-
"relative w-full rounded-lg border p-4",
|
|
140
|
-
alertStyles[variant].root,
|
|
141
|
-
className
|
|
142
|
-
)}
|
|
143
|
-
{...props}
|
|
144
|
-
/>
|
|
145
|
-
</AlertContext.Provider>
|
|
146
|
-
),
|
|
147
|
-
|
|
148
|
-
Icon: ({ className, children, ...props }) => {
|
|
149
|
-
const { variant } = useContext(AlertContext);
|
|
150
|
-
return (
|
|
151
|
-
<span
|
|
152
|
-
className={cn("h-5 w-5", alertStyles[variant].icon, className)}
|
|
153
|
-
{...props}
|
|
154
|
-
>
|
|
155
|
-
{children}
|
|
156
|
-
</span>
|
|
157
|
-
);
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
Title: ({ className, ...props }) => (
|
|
161
|
-
<h5
|
|
162
|
-
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
|
163
|
-
{...props}
|
|
164
|
-
/>
|
|
165
|
-
),
|
|
166
|
-
|
|
167
|
-
Description: ({ className, ...props }) => (
|
|
168
|
-
<div className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} />
|
|
169
|
-
),
|
|
170
|
-
};
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Slot 기반 커스터마이징
|
|
174
|
-
|
|
175
|
-
```tsx
|
|
176
|
-
// asChild 패턴으로 스타일 전달
|
|
177
|
-
import { Slot } from "@radix-ui/react-slot";
|
|
178
|
-
|
|
179
|
-
export const Button = ({
|
|
180
|
-
asChild,
|
|
181
|
-
className,
|
|
182
|
-
variant,
|
|
183
|
-
size,
|
|
184
|
-
...props
|
|
185
|
-
}) => {
|
|
186
|
-
const Comp = asChild ? Slot : "button";
|
|
187
|
-
|
|
188
|
-
return (
|
|
189
|
-
<Comp
|
|
190
|
-
className={cn(buttonVariants({ variant, size }), className)}
|
|
191
|
-
{...props}
|
|
192
|
-
/>
|
|
193
|
-
);
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// 사용: Link에 Button 스타일 적용
|
|
197
|
-
<Button asChild variant="outline">
|
|
198
|
-
<a href="/about">About</a>
|
|
199
|
-
</Button>
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## CSS Modules와 조합
|
|
203
|
-
|
|
204
|
-
```css
|
|
205
|
-
/* card.module.css */
|
|
206
|
-
.root {
|
|
207
|
-
@apply rounded-lg border;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.root[data-variant="elevated"] {
|
|
211
|
-
@apply shadow-lg;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.header {
|
|
215
|
-
@apply p-6;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.content {
|
|
219
|
-
@apply p-6 pt-0;
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
```tsx
|
|
224
|
-
import styles from "./card.module.css";
|
|
225
|
-
|
|
226
|
-
export const Card = {
|
|
227
|
-
Root: ({ variant, ...props }) => (
|
|
228
|
-
<div className={styles.root} data-variant={variant} {...props} />
|
|
229
|
-
),
|
|
230
|
-
Header: (props) => <div className={styles.header} {...props} />,
|
|
231
|
-
Content: (props) => <div className={styles.content} {...props} />,
|
|
232
|
-
};
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Reference: [Radix UI Primitives](https://www.radix-ui.com/primitives)
|