@mandujs/cli 0.15.1 → 0.15.3
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.ko.md +33 -33
- package/README.md +354 -354
- package/package.json +2 -2
- package/src/commands/check.ts +71 -7
- package/src/commands/contract.ts +173 -173
- package/src/commands/dev.ts +9 -42
- package/src/commands/guard-arch.ts +303 -303
- package/src/commands/init.ts +50 -5
- package/src/commands/monitor.ts +300 -300
- package/src/commands/openapi.ts +107 -107
- package/src/commands/registry.ts +1 -0
- package/src/commands/start.ts +9 -42
- package/src/errors/codes.ts +35 -35
- package/src/errors/index.ts +2 -2
- package/src/errors/messages.ts +143 -143
- package/src/hooks/index.ts +17 -17
- package/src/hooks/preaction.ts +256 -256
- package/src/main.ts +9 -7
- package/src/terminal/banner.ts +166 -166
- package/src/terminal/help.ts +306 -306
- package/src/terminal/index.ts +71 -71
- package/src/terminal/output.ts +295 -295
- package/src/terminal/palette.ts +30 -30
- package/src/terminal/progress.ts +327 -327
- package/src/terminal/stream-writer.ts +214 -214
- package/src/terminal/table.ts +354 -354
- package/src/terminal/theme.ts +142 -142
- package/src/util/bun.ts +6 -6
- package/src/util/fs.ts +23 -23
- package/src/util/handlers.ts +49 -5
- package/src/util/lockfile.ts +66 -0
- package/src/util/output.ts +22 -22
- package/src/util/port.ts +71 -71
- package/templates/default/AGENTS.md +96 -96
- package/templates/default/app/api/health/route.ts +13 -13
- package/templates/default/app/globals.css +49 -49
- package/templates/default/app/layout.tsx +27 -27
- package/templates/default/app/page.tsx +38 -38
- package/templates/default/src/client/shared/lib/utils.ts +16 -16
- package/templates/default/src/client/shared/ui/button.tsx +57 -57
- package/templates/default/src/client/shared/ui/card.tsx +1 -1
- package/templates/default/src/client/shared/ui/index.ts +21 -21
- package/templates/default/src/client/shared/ui/input.tsx +5 -1
- package/templates/default/tests/example.test.ts +58 -58
- package/templates/default/tests/helpers.ts +52 -52
- package/templates/default/tests/setup.ts +9 -9
- package/templates/default/tsconfig.json +23 -23
- package/templates/realtime-chat/AGENTS.md +96 -0
- package/templates/realtime-chat/app/api/chat/messages/route.ts +63 -0
- package/templates/realtime-chat/app/api/chat/stream/route.ts +85 -0
- package/templates/realtime-chat/app/api/health/route.ts +13 -0
- package/templates/realtime-chat/app/globals.css +49 -0
- package/templates/realtime-chat/app/layout.tsx +27 -0
- package/templates/realtime-chat/app/page.tsx +16 -0
- package/templates/realtime-chat/package.json +34 -0
- package/templates/realtime-chat/src/client/app/index.ts +1 -0
- package/templates/realtime-chat/src/client/entities/index.ts +1 -0
- package/templates/realtime-chat/src/client/features/chat/chat-api.ts +209 -0
- package/templates/realtime-chat/src/client/features/chat/realtime-chat-starter.client.tsx +89 -0
- package/templates/realtime-chat/src/client/features/chat/use-realtime-chat.ts +65 -0
- package/templates/realtime-chat/src/client/features/index.ts +1 -0
- package/templates/realtime-chat/src/client/pages/index.ts +1 -0
- package/templates/realtime-chat/src/client/shared/index.ts +1 -0
- package/templates/realtime-chat/src/client/shared/lib/utils.ts +16 -0
- package/templates/realtime-chat/src/client/shared/ui/button.tsx +57 -0
- package/templates/realtime-chat/src/client/shared/ui/card.tsx +78 -0
- package/templates/realtime-chat/src/client/shared/ui/index.ts +21 -0
- package/templates/realtime-chat/src/client/shared/ui/input.tsx +28 -0
- package/templates/realtime-chat/src/client/widgets/index.ts +1 -0
- package/templates/realtime-chat/src/server/api/index.ts +1 -0
- package/templates/realtime-chat/src/server/application/ai-adapter.ts +24 -0
- package/templates/realtime-chat/src/server/application/chat-store.ts +158 -0
- package/templates/realtime-chat/src/server/application/index.ts +1 -0
- package/templates/realtime-chat/src/server/core/index.ts +1 -0
- package/templates/realtime-chat/src/server/domain/index.ts +1 -0
- package/templates/realtime-chat/src/server/infra/index.ts +1 -0
- package/templates/realtime-chat/src/shared/contracts/chat.ts +29 -0
- package/templates/realtime-chat/src/shared/contracts/index.ts +1 -0
- package/templates/realtime-chat/src/shared/env/index.ts +1 -0
- package/templates/realtime-chat/src/shared/schema/index.ts +1 -0
- package/templates/realtime-chat/src/shared/types/index.ts +1 -0
- package/templates/realtime-chat/src/shared/utils/client/index.ts +1 -0
- package/templates/realtime-chat/src/shared/utils/server/index.ts +1 -0
- package/templates/realtime-chat/tests/chat-api.sse.test.ts +188 -0
- package/templates/realtime-chat/tests/chat-starter.test.ts +200 -0
- package/templates/realtime-chat/tests/chat-store.concurrency.test.ts +39 -0
- package/templates/realtime-chat/tests/example.test.ts +58 -0
- package/templates/realtime-chat/tests/helpers.ts +52 -0
- package/templates/realtime-chat/tests/setup.ts +9 -0
- package/templates/realtime-chat/tsconfig.json +23 -0
package/src/commands/init.ts
CHANGED
|
@@ -19,6 +19,23 @@ export interface InitOptions {
|
|
|
19
19
|
minimal?: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const ALLOWED_TEMPLATES = ["default", "realtime-chat"] as const;
|
|
23
|
+
const DEFAULT_MAX_BACKUP_SUFFIX_ATTEMPTS = 50;
|
|
24
|
+
const BACKUP_SUFFIX_START_INDEX = 1;
|
|
25
|
+
type AllowedTemplate = (typeof ALLOWED_TEMPLATES)[number];
|
|
26
|
+
|
|
27
|
+
export function isAllowedTemplate(template: string): template is AllowedTemplate {
|
|
28
|
+
return (ALLOWED_TEMPLATES as readonly string[]).includes(template);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function resolveTemplateName(template: string): AllowedTemplate | null {
|
|
32
|
+
const normalized = path.posix.normalize(template.replace(/\\/g, "/")).trim();
|
|
33
|
+
if (!normalized || normalized.includes("..") || normalized.startsWith("/")) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return isAllowedTemplate(normalized) ? normalized : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
22
39
|
// Files to skip based on CSS/UI options
|
|
23
40
|
const CSS_FILES = [
|
|
24
41
|
"tailwind.config.ts",
|
|
@@ -183,9 +200,16 @@ async function resolvePackageVersions(): Promise<{ coreVersion: string; cliVersi
|
|
|
183
200
|
|
|
184
201
|
export async function init(options: InitOptions = {}): Promise<boolean> {
|
|
185
202
|
const projectName = options.name || "my-mandu-app";
|
|
186
|
-
const
|
|
203
|
+
const requestedTemplate = options.template || "default";
|
|
204
|
+
const template = resolveTemplateName(requestedTemplate);
|
|
187
205
|
const targetDir = path.resolve(process.cwd(), projectName);
|
|
188
206
|
|
|
207
|
+
if (!template) {
|
|
208
|
+
printCLIError(CLI_ERROR_CODES.INIT_TEMPLATE_NOT_FOUND, { template: requestedTemplate });
|
|
209
|
+
console.error(` 사용 가능한 템플릿: ${ALLOWED_TEMPLATES.join(", ")}`);
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
189
213
|
// Handle minimal flag (shortcut for --css none --ui none)
|
|
190
214
|
const css: CSSFramework = options.minimal ? "none" : (options.css || "tailwind");
|
|
191
215
|
const ui: UILibrary = options.minimal ? "none" : (options.ui || "shadcn");
|
|
@@ -218,7 +242,7 @@ export async function init(options: InitOptions = {}): Promise<boolean> {
|
|
|
218
242
|
await fs.access(templateDir);
|
|
219
243
|
} catch {
|
|
220
244
|
printCLIError(CLI_ERROR_CODES.INIT_TEMPLATE_NOT_FOUND, { template });
|
|
221
|
-
console.error(` 사용 가능한 템플릿:
|
|
245
|
+
console.error(` 사용 가능한 템플릿: ${ALLOWED_TEMPLATES.join(", ")}`);
|
|
222
246
|
return false;
|
|
223
247
|
}
|
|
224
248
|
|
|
@@ -272,6 +296,9 @@ export async function init(options: InitOptions = {}): Promise<boolean> {
|
|
|
272
296
|
console.log(` cd ${projectName}`);
|
|
273
297
|
console.log(` bun install`);
|
|
274
298
|
console.log(` bun run dev`);
|
|
299
|
+
console.log(`\n💡 CLI 실행 참고 (환경별):`);
|
|
300
|
+
console.log(` bun run dev # 권장 (로컬 스크립트)`);
|
|
301
|
+
console.log(` bunx mandu dev # PATH에 mandu가 없을 때 대안`);
|
|
275
302
|
console.log(`\n📂 파일 구조:`);
|
|
276
303
|
console.log(` app/layout.tsx → 루트 레이아웃`);
|
|
277
304
|
console.log(` app/page.tsx → http://localhost:3000/`);
|
|
@@ -461,7 +488,18 @@ function logMcpConfigStatus(
|
|
|
461
488
|
* - 파일 없으면 새로 생성
|
|
462
489
|
* - 파일 있으면 mandu 서버만 추가/업데이트 (다른 설정 유지)
|
|
463
490
|
*/
|
|
464
|
-
|
|
491
|
+
interface SetupMcpConfigOptions {
|
|
492
|
+
maxBackupSuffixAttempts?: number;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
export const __test__ = {
|
|
496
|
+
setupMcpConfig,
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
async function setupMcpConfig(
|
|
500
|
+
targetDir: string,
|
|
501
|
+
options: SetupMcpConfigOptions = {}
|
|
502
|
+
): Promise<McpConfigResult> {
|
|
465
503
|
const mcpPath = path.join(targetDir, ".mcp.json");
|
|
466
504
|
const claudePath = path.join(targetDir, ".claude.json");
|
|
467
505
|
|
|
@@ -490,8 +528,15 @@ async function setupMcpConfig(targetDir: string): Promise<McpConfigResult> {
|
|
|
490
528
|
if (!(await fileExists(base))) {
|
|
491
529
|
return base;
|
|
492
530
|
}
|
|
493
|
-
|
|
494
|
-
|
|
531
|
+
const maxBackupSuffixAttempts =
|
|
532
|
+
options.maxBackupSuffixAttempts ?? DEFAULT_MAX_BACKUP_SUFFIX_ATTEMPTS;
|
|
533
|
+
|
|
534
|
+
for (
|
|
535
|
+
let suffixIndex = BACKUP_SUFFIX_START_INDEX;
|
|
536
|
+
suffixIndex <= maxBackupSuffixAttempts;
|
|
537
|
+
suffixIndex++
|
|
538
|
+
) {
|
|
539
|
+
const candidate = `${basePath}.bak.${suffixIndex}`;
|
|
495
540
|
if (!(await fileExists(candidate))) {
|
|
496
541
|
return candidate;
|
|
497
542
|
}
|