timsquad 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +347 -0
- package/bin/tsq.js +6 -0
- package/dist/commands/feedback.d.ts +3 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +142 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/full.d.ts +3 -0
- package/dist/commands/full.d.ts.map +1 -0
- package/dist/commands/full.js +87 -0
- package/dist/commands/full.js.map +1 -0
- package/dist/commands/git/commit.d.ts +3 -0
- package/dist/commands/git/commit.d.ts.map +1 -0
- package/dist/commands/git/commit.js +88 -0
- package/dist/commands/git/commit.js.map +1 -0
- package/dist/commands/git/index.d.ts +5 -0
- package/dist/commands/git/index.d.ts.map +1 -0
- package/dist/commands/git/index.js +5 -0
- package/dist/commands/git/index.js.map +1 -0
- package/dist/commands/git/pr.d.ts +3 -0
- package/dist/commands/git/pr.d.ts.map +1 -0
- package/dist/commands/git/pr.js +138 -0
- package/dist/commands/git/pr.js.map +1 -0
- package/dist/commands/git/release.d.ts +3 -0
- package/dist/commands/git/release.d.ts.map +1 -0
- package/dist/commands/git/release.js +158 -0
- package/dist/commands/git/release.js.map +1 -0
- package/dist/commands/git/sync.d.ts +3 -0
- package/dist/commands/git/sync.d.ts.map +1 -0
- package/dist/commands/git/sync.js +132 -0
- package/dist/commands/git/sync.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +150 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +271 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/metrics.d.ts +3 -0
- package/dist/commands/metrics.d.ts.map +1 -0
- package/dist/commands/metrics.js +299 -0
- package/dist/commands/metrics.js.map +1 -0
- package/dist/commands/quick.d.ts +3 -0
- package/dist/commands/quick.d.ts.map +1 -0
- package/dist/commands/quick.js +136 -0
- package/dist/commands/quick.js.map +1 -0
- package/dist/commands/retro.d.ts +3 -0
- package/dist/commands/retro.d.ts.map +1 -0
- package/dist/commands/retro.js +280 -0
- package/dist/commands/retro.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +127 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +213 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +34 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +108 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/project.d.ts +47 -0
- package/dist/lib/project.d.ts.map +1 -0
- package/dist/lib/project.js +191 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/template.d.ts +33 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +151 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/types/config.d.ts +75 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +66 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/feedback.d.ts +59 -0
- package/dist/types/feedback.d.ts.map +1 -0
- package/dist/types/feedback.js +26 -0
- package/dist/types/feedback.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/project.d.ts +89 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +44 -0
- package/dist/types/project.js.map +1 -0
- package/dist/utils/colors.d.ts +30 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +54 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/date.d.ts +25 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +65 -0
- package/dist/utils/date.js.map +1 -0
- package/dist/utils/fs.d.ts +49 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +84 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/prompts.d.ts +31 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +95 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/yaml.d.ts +21 -0
- package/dist/utils/yaml.d.ts.map +1 -0
- package/dist/utils/yaml.js +40 -0
- package/dist/utils/yaml.js.map +1 -0
- package/package.json +71 -0
- package/templates/common/CLAUDE.md.template +254 -0
- package/templates/common/claude/agents/tsq-dba.md +290 -0
- package/templates/common/claude/agents/tsq-designer.md +304 -0
- package/templates/common/claude/agents/tsq-developer.md +118 -0
- package/templates/common/claude/agents/tsq-planner.md +90 -0
- package/templates/common/claude/agents/tsq-prompter.md +336 -0
- package/templates/common/claude/agents/tsq-qa.md +134 -0
- package/templates/common/claude/agents/tsq-retro.md +168 -0
- package/templates/common/claude/agents/tsq-security.md +190 -0
- package/templates/common/claude/skills/architecture/SKILL.md +123 -0
- package/templates/common/claude/skills/backend/node/SKILL.md +1015 -0
- package/templates/common/claude/skills/coding/SKILL.md +171 -0
- package/templates/common/claude/skills/database/prisma/SKILL.md +357 -0
- package/templates/common/claude/skills/frontend/nextjs/SKILL.md +279 -0
- package/templates/common/claude/skills/frontend/react/SKILL.md +1729 -0
- package/templates/common/claude/skills/methodology/bdd/SKILL.md +234 -0
- package/templates/common/claude/skills/methodology/ddd/SKILL.md +311 -0
- package/templates/common/claude/skills/methodology/tdd/SKILL.md +512 -0
- package/templates/common/claude/skills/planning/SKILL.md +90 -0
- package/templates/common/claude/skills/security/SKILL.md +234 -0
- package/templates/common/claude/skills/testing/SKILL.md +146 -0
- package/templates/common/claude/skills/typescript/SKILL.md +435 -0
- package/templates/common/config.template.yaml +131 -0
- package/templates/common/timsquad/architectures/clean/ARCHITECTURE.md +49 -0
- package/templates/common/timsquad/architectures/clean/backend.xml +210 -0
- package/templates/common/timsquad/architectures/clean/frontend.xml +148 -0
- package/templates/common/timsquad/architectures/fsd/ARCHITECTURE.md +67 -0
- package/templates/common/timsquad/architectures/fsd/frontend.xml +288 -0
- package/templates/common/timsquad/architectures/hexagonal/ARCHITECTURE.md +60 -0
- package/templates/common/timsquad/architectures/hexagonal/backend.xml +300 -0
- package/templates/common/timsquad/constraints/competency-framework.xml +501 -0
- package/templates/common/timsquad/constraints/ssot-schema.xml +433 -0
- package/templates/common/timsquad/feedback/feedback-router.sh +341 -0
- package/templates/common/timsquad/feedback/routing-rules.yaml +352 -0
- package/templates/common/timsquad/generators/data-design.xml +290 -0
- package/templates/common/timsquad/generators/prd.xml +280 -0
- package/templates/common/timsquad/generators/requirements.xml +220 -0
- package/templates/common/timsquad/generators/service-spec.xml +266 -0
- package/templates/common/timsquad/logs/_example.md +81 -0
- package/templates/common/timsquad/logs/_template.md +46 -0
- package/templates/common/timsquad/patterns/cqrs.xml +127 -0
- package/templates/common/timsquad/patterns/event-sourcing.xml +85 -0
- package/templates/common/timsquad/patterns/repository.xml +64 -0
- package/templates/common/timsquad/process/state-machine.xml +343 -0
- package/templates/common/timsquad/process/validation-rules.xml +308 -0
- package/templates/common/timsquad/process/workflow-base.xml +202 -0
- package/templates/common/timsquad/retrospective/cycle-report.template.md +205 -0
- package/templates/common/timsquad/retrospective/metrics/metrics-schema.json +203 -0
- package/templates/common/timsquad/retrospective/patterns/failure-patterns.md +199 -0
- package/templates/common/timsquad/retrospective/patterns/success-patterns.md +262 -0
- package/templates/common/timsquad/retrospective/retrospective-config.xml +294 -0
- package/templates/common/timsquad/retrospective/retrospective-state.xml +210 -0
- package/templates/common/timsquad/ssot/adr/ADR-000-template.md +121 -0
- package/templates/common/timsquad/ssot/adr/ADR-001-example.md +115 -0
- package/templates/common/timsquad/ssot/data-design.template.md +132 -0
- package/templates/common/timsquad/ssot/deployment-spec.template.md +384 -0
- package/templates/common/timsquad/ssot/env-config.template.md +346 -0
- package/templates/common/timsquad/ssot/error-codes.template.md +114 -0
- package/templates/common/timsquad/ssot/functional-spec.template.md +185 -0
- package/templates/common/timsquad/ssot/glossary.template.md +148 -0
- package/templates/common/timsquad/ssot/integration-spec.template.md +391 -0
- package/templates/common/timsquad/ssot/planning.template.md +94 -0
- package/templates/common/timsquad/ssot/prd.template.md +102 -0
- package/templates/common/timsquad/ssot/requirements.template.md +117 -0
- package/templates/common/timsquad/ssot/security-spec.template.md +309 -0
- package/templates/common/timsquad/ssot/service-spec.template.md +194 -0
- package/templates/common/timsquad/ssot/test-spec.template.md +264 -0
- package/templates/common/timsquad/ssot/ui-ux-spec.template.md +262 -0
- package/templates/common/timsquad/state/workspace.xml +217 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs
|
|
3
|
+
description: Next.js App Router 개발 가이드라인
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<skill name="nextjs">
|
|
8
|
+
<purpose>Next.js 15+ App Router 기반 개발 가이드라인</purpose>
|
|
9
|
+
|
|
10
|
+
<philosophy>
|
|
11
|
+
<principle>Server First - 기본은 서버 컴포넌트</principle>
|
|
12
|
+
<principle>Progressive Enhancement - 필요할 때만 클라이언트</principle>
|
|
13
|
+
<principle>Colocation - 관련 파일은 가까이</principle>
|
|
14
|
+
</philosophy>
|
|
15
|
+
|
|
16
|
+
<app-router-structure>
|
|
17
|
+
<structure>
|
|
18
|
+
<![CDATA[
|
|
19
|
+
app/
|
|
20
|
+
├── layout.tsx # 루트 레이아웃 (필수)
|
|
21
|
+
├── page.tsx # 홈페이지 (/)
|
|
22
|
+
├── loading.tsx # 로딩 UI
|
|
23
|
+
├── error.tsx # 에러 UI
|
|
24
|
+
├── not-found.tsx # 404 UI
|
|
25
|
+
│
|
|
26
|
+
├── (auth)/ # Route Group (URL에 미포함)
|
|
27
|
+
│ ├── login/
|
|
28
|
+
│ │ └── page.tsx # /login
|
|
29
|
+
│ └── register/
|
|
30
|
+
│ └── page.tsx # /register
|
|
31
|
+
│
|
|
32
|
+
├── dashboard/
|
|
33
|
+
│ ├── layout.tsx # 대시보드 레이아웃
|
|
34
|
+
│ ├── page.tsx # /dashboard
|
|
35
|
+
│ └── settings/
|
|
36
|
+
│ └── page.tsx # /dashboard/settings
|
|
37
|
+
│
|
|
38
|
+
├── users/
|
|
39
|
+
│ ├── page.tsx # /users (목록)
|
|
40
|
+
│ └── [id]/
|
|
41
|
+
│ ├── page.tsx # /users/:id (상세)
|
|
42
|
+
│ └── edit/
|
|
43
|
+
│ └── page.tsx # /users/:id/edit
|
|
44
|
+
│
|
|
45
|
+
└── api/ # API Routes
|
|
46
|
+
└── users/
|
|
47
|
+
└── route.ts # /api/users
|
|
48
|
+
]]>
|
|
49
|
+
</structure>
|
|
50
|
+
</app-router-structure>
|
|
51
|
+
|
|
52
|
+
<server-vs-client>
|
|
53
|
+
<comparison>
|
|
54
|
+
<server-component>
|
|
55
|
+
<use-when>데이터 페칭, DB 접근, 민감한 정보, 정적 콘텐츠</use-when>
|
|
56
|
+
<benefits>번들 크기 감소, SEO, 빠른 초기 로딩</benefits>
|
|
57
|
+
<example>
|
|
58
|
+
<![CDATA[
|
|
59
|
+
// app/users/page.tsx (Server Component - 기본)
|
|
60
|
+
import { db } from '@/lib/db';
|
|
61
|
+
|
|
62
|
+
export default async function UsersPage() {
|
|
63
|
+
const users = await db.user.findMany();
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ul>
|
|
67
|
+
{users.map(user => (
|
|
68
|
+
<li key={user.id}>{user.name}</li>
|
|
69
|
+
))}
|
|
70
|
+
</ul>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
]]>
|
|
74
|
+
</example>
|
|
75
|
+
</server-component>
|
|
76
|
+
<client-component>
|
|
77
|
+
<use-when>인터랙션, 브라우저 API, 상태, 이벤트 핸들러</use-when>
|
|
78
|
+
<marker>'use client' 상단에 선언</marker>
|
|
79
|
+
<example>
|
|
80
|
+
<![CDATA[
|
|
81
|
+
// components/counter.tsx
|
|
82
|
+
'use client';
|
|
83
|
+
|
|
84
|
+
import { useState } from 'react';
|
|
85
|
+
|
|
86
|
+
export function Counter() {
|
|
87
|
+
const [count, setCount] = useState(0);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<button onClick={() => setCount(c => c + 1)}>
|
|
91
|
+
Count: {count}
|
|
92
|
+
</button>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
]]>
|
|
96
|
+
</example>
|
|
97
|
+
</client-component>
|
|
98
|
+
</comparison>
|
|
99
|
+
<decision-tree>
|
|
100
|
+
<![CDATA[
|
|
101
|
+
데이터 페칭 필요? ─────────────► Server Component
|
|
102
|
+
│ No
|
|
103
|
+
▼
|
|
104
|
+
인터랙션/이벤트 필요? ─────────► Client Component ('use client')
|
|
105
|
+
│ No
|
|
106
|
+
▼
|
|
107
|
+
브라우저 API 필요? ───────────► Client Component
|
|
108
|
+
│ No
|
|
109
|
+
▼
|
|
110
|
+
Server Component (기본)
|
|
111
|
+
]]>
|
|
112
|
+
</decision-tree>
|
|
113
|
+
</server-vs-client>
|
|
114
|
+
|
|
115
|
+
<data-fetching>
|
|
116
|
+
<pattern name="서버 컴포넌트에서 직접 fetch">
|
|
117
|
+
<example>
|
|
118
|
+
<![CDATA[
|
|
119
|
+
// app/posts/page.tsx
|
|
120
|
+
async function getPosts() {
|
|
121
|
+
const res = await fetch('https://api.example.com/posts', {
|
|
122
|
+
next: { revalidate: 60 }, // 60초마다 재검증
|
|
123
|
+
});
|
|
124
|
+
return res.json();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default async function PostsPage() {
|
|
128
|
+
const posts = await getPosts();
|
|
129
|
+
return <PostList posts={posts} />;
|
|
130
|
+
}
|
|
131
|
+
]]>
|
|
132
|
+
</example>
|
|
133
|
+
</pattern>
|
|
134
|
+
<pattern name="Server Actions">
|
|
135
|
+
<example>
|
|
136
|
+
<![CDATA[
|
|
137
|
+
// app/actions/user.ts
|
|
138
|
+
'use server';
|
|
139
|
+
|
|
140
|
+
import { db } from '@/lib/db';
|
|
141
|
+
import { revalidatePath } from 'next/cache';
|
|
142
|
+
|
|
143
|
+
export async function createUser(formData: FormData) {
|
|
144
|
+
const name = formData.get('name') as string;
|
|
145
|
+
const email = formData.get('email') as string;
|
|
146
|
+
|
|
147
|
+
await db.user.create({ data: { name, email } });
|
|
148
|
+
|
|
149
|
+
revalidatePath('/users');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 사용 (Client Component에서)
|
|
153
|
+
'use client';
|
|
154
|
+
|
|
155
|
+
import { createUser } from '@/app/actions/user';
|
|
156
|
+
|
|
157
|
+
export function CreateUserForm() {
|
|
158
|
+
return (
|
|
159
|
+
<form action={createUser}>
|
|
160
|
+
<input name="name" required />
|
|
161
|
+
<input name="email" type="email" required />
|
|
162
|
+
<button type="submit">Create</button>
|
|
163
|
+
</form>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
]]>
|
|
167
|
+
</example>
|
|
168
|
+
</pattern>
|
|
169
|
+
<caching>
|
|
170
|
+
<option name="force-cache">기본값, 캐시 사용</option>
|
|
171
|
+
<option name="no-store">캐시 안 함, 항상 새로 요청</option>
|
|
172
|
+
<option name="revalidate: N">N초마다 재검증</option>
|
|
173
|
+
<option name="revalidatePath()">특정 경로 재검증</option>
|
|
174
|
+
<option name="revalidateTag()">태그로 재검증</option>
|
|
175
|
+
</caching>
|
|
176
|
+
</data-fetching>
|
|
177
|
+
|
|
178
|
+
<metadata>
|
|
179
|
+
<pattern name="정적 메타데이터">
|
|
180
|
+
<![CDATA[
|
|
181
|
+
// app/about/page.tsx
|
|
182
|
+
import type { Metadata } from 'next';
|
|
183
|
+
|
|
184
|
+
export const metadata: Metadata = {
|
|
185
|
+
title: 'About Us',
|
|
186
|
+
description: 'Learn more about our company',
|
|
187
|
+
};
|
|
188
|
+
]]>
|
|
189
|
+
</pattern>
|
|
190
|
+
<pattern name="동적 메타데이터">
|
|
191
|
+
<![CDATA[
|
|
192
|
+
// app/users/[id]/page.tsx
|
|
193
|
+
import type { Metadata } from 'next';
|
|
194
|
+
|
|
195
|
+
type Props = { params: Promise<{ id: string }> };
|
|
196
|
+
|
|
197
|
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
198
|
+
const { id } = await params;
|
|
199
|
+
const user = await getUser(id);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
title: user.name,
|
|
203
|
+
description: `Profile of ${user.name}`,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
]]>
|
|
207
|
+
</pattern>
|
|
208
|
+
</metadata>
|
|
209
|
+
|
|
210
|
+
<loading-error>
|
|
211
|
+
<pattern name="loading.tsx">
|
|
212
|
+
<![CDATA[
|
|
213
|
+
// app/dashboard/loading.tsx
|
|
214
|
+
export default function Loading() {
|
|
215
|
+
return <DashboardSkeleton />;
|
|
216
|
+
}
|
|
217
|
+
]]>
|
|
218
|
+
</pattern>
|
|
219
|
+
<pattern name="error.tsx">
|
|
220
|
+
<![CDATA[
|
|
221
|
+
// app/dashboard/error.tsx
|
|
222
|
+
'use client';
|
|
223
|
+
|
|
224
|
+
export default function Error({
|
|
225
|
+
error,
|
|
226
|
+
reset,
|
|
227
|
+
}: {
|
|
228
|
+
error: Error & { digest?: string };
|
|
229
|
+
reset: () => void;
|
|
230
|
+
}) {
|
|
231
|
+
return (
|
|
232
|
+
<div>
|
|
233
|
+
<h2>Something went wrong!</h2>
|
|
234
|
+
<button onClick={reset}>Try again</button>
|
|
235
|
+
</div>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
]]>
|
|
239
|
+
</pattern>
|
|
240
|
+
</loading-error>
|
|
241
|
+
|
|
242
|
+
<rules>
|
|
243
|
+
<category name="컴포넌트">
|
|
244
|
+
<must>기본은 Server Component</must>
|
|
245
|
+
<must>인터랙션 필요할 때만 'use client'</must>
|
|
246
|
+
<must>Client Component는 작게 유지 (leaf에 배치)</must>
|
|
247
|
+
<must-not>Server Component에서 useState/useEffect</must-not>
|
|
248
|
+
<must-not>불필요한 'use client'</must-not>
|
|
249
|
+
</category>
|
|
250
|
+
<category name="데이터">
|
|
251
|
+
<must>Server Component에서 데이터 페칭</must>
|
|
252
|
+
<must>mutation은 Server Actions 사용</must>
|
|
253
|
+
<must>적절한 캐싱 전략 설정</must>
|
|
254
|
+
<must-not>Client Component에서 직접 DB 접근</must-not>
|
|
255
|
+
</category>
|
|
256
|
+
<category name="라우팅">
|
|
257
|
+
<must>파일 기반 라우팅 규칙 준수</must>
|
|
258
|
+
<must>Route Group으로 레이아웃 관리</must>
|
|
259
|
+
<must>loading.tsx, error.tsx 제공</must>
|
|
260
|
+
</category>
|
|
261
|
+
</rules>
|
|
262
|
+
|
|
263
|
+
<performance>
|
|
264
|
+
<optimization name="이미지">next/image 사용, sizes 속성</optimization>
|
|
265
|
+
<optimization name="폰트">next/font로 최적화</optimization>
|
|
266
|
+
<optimization name="링크">next/link로 프리페칭</optimization>
|
|
267
|
+
<optimization name="동적 import">무거운 컴포넌트 지연 로딩</optimization>
|
|
268
|
+
</performance>
|
|
269
|
+
|
|
270
|
+
<checklist>
|
|
271
|
+
<item priority="critical">Server Component 기본 사용</item>
|
|
272
|
+
<item priority="critical">'use client' 최소화</item>
|
|
273
|
+
<item priority="critical">Server Actions로 mutation</item>
|
|
274
|
+
<item priority="high">적절한 캐싱 전략</item>
|
|
275
|
+
<item priority="high">loading.tsx, error.tsx 구현</item>
|
|
276
|
+
<item priority="high">Metadata 설정</item>
|
|
277
|
+
<item priority="medium">이미지/폰트 최적화</item>
|
|
278
|
+
</checklist>
|
|
279
|
+
</skill>
|